@automattic/jetpack-ai-client 0.20.1 → 0.22.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 (174) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/build/{hooks → ai-client/src/hooks}/use-image-generator/constants.d.ts +6 -20
  3. package/build/ai-client/src/hooks/use-image-generator/constants.js +21 -0
  4. package/build/{hooks → ai-client/src/hooks}/use-image-generator/index.d.ts +0 -1
  5. package/build/{hooks → ai-client/src/hooks}/use-image-generator/index.js +0 -10
  6. package/build/{logo-generator → ai-client/src/logo-generator}/components/generator-modal.js +27 -8
  7. package/build/{logo-generator → ai-client/src/logo-generator}/components/history-carousel.js +1 -1
  8. package/build/{logo-generator → ai-client/src/logo-generator}/components/logo-presenter.js +8 -2
  9. package/build/ai-client/src/logo-generator/components/prompt.d.ts +6 -0
  10. package/build/{logo-generator → ai-client/src/logo-generator}/components/prompt.js +47 -19
  11. package/build/{logo-generator → ai-client/src/logo-generator}/components/upgrade-screen.js +6 -2
  12. package/build/{logo-generator → ai-client/src/logo-generator}/constants.d.ts +1 -0
  13. package/build/{logo-generator → ai-client/src/logo-generator}/constants.js +1 -0
  14. package/build/{logo-generator → ai-client/src/logo-generator}/hooks/use-checkout.js +0 -3
  15. package/build/{logo-generator → ai-client/src/logo-generator}/hooks/use-fair-usage-notice-message.js +5 -1
  16. package/build/{logo-generator → ai-client/src/logo-generator}/hooks/use-logo-generator.d.ts +3 -2
  17. package/build/{logo-generator → ai-client/src/logo-generator}/hooks/use-logo-generator.js +57 -3
  18. package/build/{logo-generator → ai-client/src/logo-generator}/store/constants.d.ts +1 -1
  19. package/build/{logo-generator → ai-client/src/logo-generator}/store/constants.js +1 -1
  20. package/build/{logo-generator → ai-client/src/logo-generator}/store/initial-state.js +6 -0
  21. package/build/{logo-generator → ai-client/src/logo-generator}/store/types.d.ts +6 -4
  22. package/build/{logo-generator → ai-client/src/logo-generator}/types.d.ts +0 -1
  23. package/build/{types.d.ts → ai-client/src/types.d.ts} +6 -1
  24. package/build/{types.js → ai-client/src/types.js} +4 -0
  25. package/build/components/tools/jp-redirect/index.d.ts +20 -0
  26. package/build/components/tools/jp-redirect/index.js +50 -0
  27. package/build/components/tools/jp-redirect/types.d.ts +39 -0
  28. package/build/components/tools/jp-redirect/types.js +1 -0
  29. package/package.json +18 -18
  30. package/src/hooks/use-image-generator/constants.ts +27 -23
  31. package/src/hooks/use-image-generator/index.ts +0 -11
  32. package/src/logo-generator/components/generator-modal.tsx +29 -9
  33. package/src/logo-generator/components/history-carousel.tsx +1 -0
  34. package/src/logo-generator/components/logo-presenter.tsx +15 -1
  35. package/src/logo-generator/components/prompt.tsx +55 -24
  36. package/src/logo-generator/components/upgrade-screen.tsx +8 -2
  37. package/src/logo-generator/constants.ts +1 -0
  38. package/src/logo-generator/hooks/use-checkout.ts +0 -5
  39. package/src/logo-generator/hooks/use-fair-usage-notice-message.tsx +6 -7
  40. package/src/logo-generator/hooks/use-logo-generator.ts +100 -31
  41. package/src/logo-generator/store/constants.ts +1 -1
  42. package/src/logo-generator/store/initial-state.ts +6 -0
  43. package/src/logo-generator/store/types.ts +9 -4
  44. package/src/logo-generator/types.ts +0 -1
  45. package/src/types.ts +12 -1
  46. package/build/hooks/use-image-generator/constants.js +0 -40
  47. package/build/logo-generator/components/prompt.d.ts +0 -7
  48. /package/build/{api-fetch → ai-client/src/api-fetch}/index.d.ts +0 -0
  49. /package/build/{api-fetch → ai-client/src/api-fetch}/index.js +0 -0
  50. /package/build/{ask-question → ai-client/src/ask-question}/index.d.ts +0 -0
  51. /package/build/{ask-question → ai-client/src/ask-question}/index.js +0 -0
  52. /package/build/{ask-question → ai-client/src/ask-question}/sync.d.ts +0 -0
  53. /package/build/{ask-question → ai-client/src/ask-question}/sync.js +0 -0
  54. /package/build/{audio-transcription → ai-client/src/audio-transcription}/index.d.ts +0 -0
  55. /package/build/{audio-transcription → ai-client/src/audio-transcription}/index.js +0 -0
  56. /package/build/{components → ai-client/src/components}/ai-control/ai-control.d.ts +0 -0
  57. /package/build/{components → ai-client/src/components}/ai-control/ai-control.js +0 -0
  58. /package/build/{components → ai-client/src/components}/ai-control/block-ai-control.d.ts +0 -0
  59. /package/build/{components → ai-client/src/components}/ai-control/block-ai-control.js +0 -0
  60. /package/build/{components → ai-client/src/components}/ai-control/extension-ai-control.d.ts +0 -0
  61. /package/build/{components → ai-client/src/components}/ai-control/extension-ai-control.js +0 -0
  62. /package/build/{components → ai-client/src/components}/ai-control/index.d.ts +0 -0
  63. /package/build/{components → ai-client/src/components}/ai-control/index.js +0 -0
  64. /package/build/{components → ai-client/src/components}/ai-status-indicator/index.d.ts +0 -0
  65. /package/build/{components → ai-client/src/components}/ai-status-indicator/index.js +0 -0
  66. /package/build/{components → ai-client/src/components}/audio-duration-display/index.d.ts +0 -0
  67. /package/build/{components → ai-client/src/components}/audio-duration-display/index.js +0 -0
  68. /package/build/{components → ai-client/src/components}/audio-duration-display/lib/media.d.ts +0 -0
  69. /package/build/{components → ai-client/src/components}/audio-duration-display/lib/media.js +0 -0
  70. /package/build/{components → ai-client/src/components}/index.d.ts +0 -0
  71. /package/build/{components → ai-client/src/components}/index.js +0 -0
  72. /package/build/{components → ai-client/src/components}/message/index.d.ts +0 -0
  73. /package/build/{components → ai-client/src/components}/message/index.js +0 -0
  74. /package/build/{data-flow → ai-client/src/data-flow}/context.d.ts +0 -0
  75. /package/build/{data-flow → ai-client/src/data-flow}/context.js +0 -0
  76. /package/build/{data-flow → ai-client/src/data-flow}/index.d.ts +0 -0
  77. /package/build/{data-flow → ai-client/src/data-flow}/index.js +0 -0
  78. /package/build/{data-flow → ai-client/src/data-flow}/use-ai-context.d.ts +0 -0
  79. /package/build/{data-flow → ai-client/src/data-flow}/use-ai-context.js +0 -0
  80. /package/build/{data-flow → ai-client/src/data-flow}/with-ai-assistant-data.d.ts +0 -0
  81. /package/build/{data-flow → ai-client/src/data-flow}/with-ai-assistant-data.js +0 -0
  82. /package/build/{hooks → ai-client/src/hooks}/use-ai-suggestions/index.d.ts +0 -0
  83. /package/build/{hooks → ai-client/src/hooks}/use-ai-suggestions/index.js +0 -0
  84. /package/build/{hooks → ai-client/src/hooks}/use-audio-transcription/index.d.ts +0 -0
  85. /package/build/{hooks → ai-client/src/hooks}/use-audio-transcription/index.js +0 -0
  86. /package/build/{hooks → ai-client/src/hooks}/use-audio-validation/index.d.ts +0 -0
  87. /package/build/{hooks → ai-client/src/hooks}/use-audio-validation/index.js +0 -0
  88. /package/build/{hooks → ai-client/src/hooks}/use-media-recording/index.d.ts +0 -0
  89. /package/build/{hooks → ai-client/src/hooks}/use-media-recording/index.js +0 -0
  90. /package/build/{hooks → ai-client/src/hooks}/use-save-to-media-library/index.d.ts +0 -0
  91. /package/build/{hooks → ai-client/src/hooks}/use-save-to-media-library/index.js +0 -0
  92. /package/build/{hooks → ai-client/src/hooks}/use-transcription-post-processing/index.d.ts +0 -0
  93. /package/build/{hooks → ai-client/src/hooks}/use-transcription-post-processing/index.js +0 -0
  94. /package/build/{icons → ai-client/src/icons}/ai-assistant.d.ts +0 -0
  95. /package/build/{icons → ai-client/src/icons}/ai-assistant.js +0 -0
  96. /package/build/{icons → ai-client/src/icons}/error-exclamation.d.ts +0 -0
  97. /package/build/{icons → ai-client/src/icons}/error-exclamation.js +0 -0
  98. /package/build/{icons → ai-client/src/icons}/index.d.ts +0 -0
  99. /package/build/{icons → ai-client/src/icons}/index.js +0 -0
  100. /package/build/{icons → ai-client/src/icons}/mic.d.ts +0 -0
  101. /package/build/{icons → ai-client/src/icons}/mic.js +0 -0
  102. /package/build/{icons → ai-client/src/icons}/origami-plane.d.ts +0 -0
  103. /package/build/{icons → ai-client/src/icons}/origami-plane.js +0 -0
  104. /package/build/{icons → ai-client/src/icons}/player-pause.d.ts +0 -0
  105. /package/build/{icons → ai-client/src/icons}/player-pause.js +0 -0
  106. /package/build/{icons → ai-client/src/icons}/player-play.d.ts +0 -0
  107. /package/build/{icons → ai-client/src/icons}/player-play.js +0 -0
  108. /package/build/{icons → ai-client/src/icons}/player-stop.d.ts +0 -0
  109. /package/build/{icons → ai-client/src/icons}/player-stop.js +0 -0
  110. /package/build/{icons → ai-client/src/icons}/speak-tone.d.ts +0 -0
  111. /package/build/{icons → ai-client/src/icons}/speak-tone.js +0 -0
  112. /package/build/{index.d.ts → ai-client/src/index.d.ts} +0 -0
  113. /package/build/{index.js → ai-client/src/index.js} +0 -0
  114. /package/build/{jwt → ai-client/src/jwt}/index.d.ts +0 -0
  115. /package/build/{jwt → ai-client/src/jwt}/index.js +0 -0
  116. /package/build/{libs → ai-client/src/libs}/index.d.ts +0 -0
  117. /package/build/{libs → ai-client/src/libs}/index.js +0 -0
  118. /package/build/{libs → ai-client/src/libs}/markdown/html-to-markdown.d.ts +0 -0
  119. /package/build/{libs → ai-client/src/libs}/markdown/html-to-markdown.js +0 -0
  120. /package/build/{libs → ai-client/src/libs}/markdown/index.d.ts +0 -0
  121. /package/build/{libs → ai-client/src/libs}/markdown/index.js +0 -0
  122. /package/build/{libs → ai-client/src/libs}/markdown/markdown-to-html.d.ts +0 -0
  123. /package/build/{libs → ai-client/src/libs}/markdown/markdown-to-html.js +0 -0
  124. /package/build/{logo-generator → ai-client/src/logo-generator}/assets/icons/ai.d.ts +0 -0
  125. /package/build/{logo-generator → ai-client/src/logo-generator}/assets/icons/ai.js +0 -0
  126. /package/build/{logo-generator → ai-client/src/logo-generator}/assets/icons/check.d.ts +0 -0
  127. /package/build/{logo-generator → ai-client/src/logo-generator}/assets/icons/check.js +0 -0
  128. /package/build/{logo-generator → ai-client/src/logo-generator}/assets/icons/logo.d.ts +0 -0
  129. /package/build/{logo-generator → ai-client/src/logo-generator}/assets/icons/logo.js +0 -0
  130. /package/build/{logo-generator → ai-client/src/logo-generator}/assets/icons/media.d.ts +0 -0
  131. /package/build/{logo-generator → ai-client/src/logo-generator}/assets/icons/media.js +0 -0
  132. /package/build/{logo-generator → ai-client/src/logo-generator}/components/fair-usage-notice.d.ts +0 -0
  133. /package/build/{logo-generator → ai-client/src/logo-generator}/components/fair-usage-notice.js +0 -0
  134. /package/build/{logo-generator → ai-client/src/logo-generator}/components/feature-fetch-failure-screen.d.ts +0 -0
  135. /package/build/{logo-generator → ai-client/src/logo-generator}/components/feature-fetch-failure-screen.js +0 -0
  136. /package/build/{logo-generator → ai-client/src/logo-generator}/components/first-load-screen.d.ts +0 -0
  137. /package/build/{logo-generator → ai-client/src/logo-generator}/components/first-load-screen.js +0 -0
  138. /package/build/{logo-generator → ai-client/src/logo-generator}/components/generator-modal.d.ts +0 -0
  139. /package/build/{logo-generator → ai-client/src/logo-generator}/components/history-carousel.d.ts +0 -0
  140. /package/build/{logo-generator → ai-client/src/logo-generator}/components/image-loader.d.ts +0 -0
  141. /package/build/{logo-generator → ai-client/src/logo-generator}/components/image-loader.js +0 -0
  142. /package/build/{logo-generator → ai-client/src/logo-generator}/components/logo-presenter.d.ts +0 -0
  143. /package/build/{logo-generator → ai-client/src/logo-generator}/components/upgrade-nudge.d.ts +0 -0
  144. /package/build/{logo-generator → ai-client/src/logo-generator}/components/upgrade-nudge.js +0 -0
  145. /package/build/{logo-generator → ai-client/src/logo-generator}/components/upgrade-screen.d.ts +0 -0
  146. /package/build/{logo-generator → ai-client/src/logo-generator}/components/visit-site-banner.d.ts +0 -0
  147. /package/build/{logo-generator → ai-client/src/logo-generator}/components/visit-site-banner.js +0 -0
  148. /package/build/{logo-generator → ai-client/src/logo-generator}/hooks/use-checkout.d.ts +0 -0
  149. /package/build/{logo-generator → ai-client/src/logo-generator}/hooks/use-fair-usage-notice-message.d.ts +0 -0
  150. /package/build/{logo-generator → ai-client/src/logo-generator}/hooks/use-request-errors.d.ts +0 -0
  151. /package/build/{logo-generator → ai-client/src/logo-generator}/hooks/use-request-errors.js +0 -0
  152. /package/build/{logo-generator → ai-client/src/logo-generator}/index.d.ts +0 -0
  153. /package/build/{logo-generator → ai-client/src/logo-generator}/index.js +0 -0
  154. /package/build/{logo-generator → ai-client/src/logo-generator}/lib/logo-storage.d.ts +0 -0
  155. /package/build/{logo-generator → ai-client/src/logo-generator}/lib/logo-storage.js +0 -0
  156. /package/build/{logo-generator → ai-client/src/logo-generator}/lib/media-exists.d.ts +0 -0
  157. /package/build/{logo-generator → ai-client/src/logo-generator}/lib/media-exists.js +0 -0
  158. /package/build/{logo-generator → ai-client/src/logo-generator}/lib/set-site-logo.d.ts +0 -0
  159. /package/build/{logo-generator → ai-client/src/logo-generator}/lib/set-site-logo.js +0 -0
  160. /package/build/{logo-generator → ai-client/src/logo-generator}/lib/wpcom-limited-request.d.ts +0 -0
  161. /package/build/{logo-generator → ai-client/src/logo-generator}/lib/wpcom-limited-request.js +0 -0
  162. /package/build/{logo-generator → ai-client/src/logo-generator}/store/actions.d.ts +0 -0
  163. /package/build/{logo-generator → ai-client/src/logo-generator}/store/actions.js +0 -0
  164. /package/build/{logo-generator → ai-client/src/logo-generator}/store/index.d.ts +0 -0
  165. /package/build/{logo-generator → ai-client/src/logo-generator}/store/index.js +0 -0
  166. /package/build/{logo-generator → ai-client/src/logo-generator}/store/initial-state.d.ts +0 -0
  167. /package/build/{logo-generator → ai-client/src/logo-generator}/store/reducer.d.ts +0 -0
  168. /package/build/{logo-generator → ai-client/src/logo-generator}/store/reducer.js +0 -0
  169. /package/build/{logo-generator → ai-client/src/logo-generator}/store/selectors.d.ts +0 -0
  170. /package/build/{logo-generator → ai-client/src/logo-generator}/store/selectors.js +0 -0
  171. /package/build/{logo-generator → ai-client/src/logo-generator}/store/types.js +0 -0
  172. /package/build/{logo-generator → ai-client/src/logo-generator}/types.js +0 -0
  173. /package/build/{suggestions-event-source → ai-client/src/suggestions-event-source}/index.d.ts +0 -0
  174. /package/build/{suggestions-event-source → ai-client/src/suggestions-event-source}/index.js +0 -0
package/CHANGELOG.md CHANGED
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.22.0] - 2024-10-21
9
+ ### Changed
10
+ - AI Client: Add types for AI assistant feature payload data branch featuresControl. [#39826]
11
+
12
+ ## [0.21.0] - 2024-10-14
13
+ ### Added
14
+ - AI Client: Add image styles 'auto' and 'none' to the logo generator. Order styles so those are on top in the dropdown selector. [#39689]
15
+ - AI Client: Add prompt processing and style guess function for logo generator [#39712]
16
+
17
+ ### Changed
18
+ - AI Client: Change plans limit to use and accept new 3000 value. [#39705]
19
+ - AI Client: Change upgrade copy edit and redirect URL. [#39671]
20
+ - AI Client: If site details show empty or default, do not trigger a logo generation, use empty placeholders. [#39536]
21
+ - AI Client: Remove provision of image styles via flag prop and internal definition, take it from ai-assistant-feature payload now. [#39589]
22
+ - Updated package dependencies. [#39669] [#39707]
23
+
8
24
  ## [0.20.1] - 2024-10-07
9
25
  ### Changed
10
26
  - Updated package dependencies. [#39594]
@@ -423,6 +439,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
423
439
  - Updated package dependencies. [#31659]
424
440
  - Updated package dependencies. [#31785]
425
441
 
442
+ [0.22.0]: https://github.com/Automattic/jetpack-ai-client/compare/v0.21.0...v0.22.0
443
+ [0.21.0]: https://github.com/Automattic/jetpack-ai-client/compare/v0.20.1...v0.21.0
426
444
  [0.20.1]: https://github.com/Automattic/jetpack-ai-client/compare/v0.20.0...v0.20.1
427
445
  [0.20.0]: https://github.com/Automattic/jetpack-ai-client/compare/v0.19.0...v0.20.0
428
446
  [0.19.0]: https://github.com/Automattic/jetpack-ai-client/compare/v0.18.1...v0.19.0
@@ -16,24 +16,10 @@ export declare const IMAGE_STYLE_3D_MODEL = "3d-model";
16
16
  export declare const IMAGE_STYLE_PIXEL_ART = "pixel-art";
17
17
  export declare const IMAGE_STYLE_TEXTURE = "texture";
18
18
  export declare const IMAGE_STYLE_MONTY_PYTHON = "monty-python";
19
- export declare const IMAGE_STYLE_LABELS: {
20
- enhance: string;
21
- anime: string;
22
- photographic: string;
23
- "digital-art": string;
24
- comicbook: string;
25
- "fantasy-art": string;
26
- "analog-film": string;
27
- neonpunk: string;
28
- isometric: string;
29
- lowpoly: string;
30
- origami: string;
31
- "line-art": string;
32
- "craft-clay": string;
33
- cinematic: string;
34
- "3d-model": string;
35
- "pixel-art": string;
36
- texture: string;
37
- "monty-python": string;
19
+ export declare const IMAGE_STYLE_AUTO = "auto";
20
+ export declare const IMAGE_STYLE_NONE = "none";
21
+ export type ImageStyle = typeof IMAGE_STYLE_ENHANCE | typeof IMAGE_STYLE_ANIME | typeof IMAGE_STYLE_PHOTOGRAPHIC | typeof IMAGE_STYLE_DIGITAL_ART | typeof IMAGE_STYLE_COMICBOOK | typeof IMAGE_STYLE_FANTASY_ART | typeof IMAGE_STYLE_ANALOG_FILM | typeof IMAGE_STYLE_NEONPUNK | typeof IMAGE_STYLE_ISOMETRIC | typeof IMAGE_STYLE_LOWPOLY | typeof IMAGE_STYLE_ORIGAMI | typeof IMAGE_STYLE_LINE_ART | typeof IMAGE_STYLE_CRAFT_CLAY | typeof IMAGE_STYLE_CINEMATIC | typeof IMAGE_STYLE_3D_MODEL | typeof IMAGE_STYLE_PIXEL_ART | typeof IMAGE_STYLE_TEXTURE | typeof IMAGE_STYLE_MONTY_PYTHON | typeof IMAGE_STYLE_AUTO | typeof IMAGE_STYLE_NONE;
22
+ export type ImageStyleObject = {
23
+ label: string;
24
+ value: ImageStyle;
38
25
  };
39
- export type ImageStyle = keyof typeof IMAGE_STYLE_LABELS;
@@ -0,0 +1,21 @@
1
+ // Styles
2
+ export const IMAGE_STYLE_ENHANCE = 'enhance';
3
+ export const IMAGE_STYLE_ANIME = 'anime';
4
+ export const IMAGE_STYLE_PHOTOGRAPHIC = 'photographic';
5
+ export const IMAGE_STYLE_DIGITAL_ART = 'digital-art';
6
+ export const IMAGE_STYLE_COMICBOOK = 'comicbook';
7
+ export const IMAGE_STYLE_FANTASY_ART = 'fantasy-art';
8
+ export const IMAGE_STYLE_ANALOG_FILM = 'analog-film';
9
+ export const IMAGE_STYLE_NEONPUNK = 'neonpunk';
10
+ export const IMAGE_STYLE_ISOMETRIC = 'isometric';
11
+ export const IMAGE_STYLE_LOWPOLY = 'lowpoly';
12
+ export const IMAGE_STYLE_ORIGAMI = 'origami';
13
+ export const IMAGE_STYLE_LINE_ART = 'line-art';
14
+ export const IMAGE_STYLE_CRAFT_CLAY = 'craft-clay';
15
+ export const IMAGE_STYLE_CINEMATIC = 'cinematic';
16
+ export const IMAGE_STYLE_3D_MODEL = '3d-model';
17
+ export const IMAGE_STYLE_PIXEL_ART = 'pixel-art';
18
+ export const IMAGE_STYLE_TEXTURE = 'texture';
19
+ export const IMAGE_STYLE_MONTY_PYTHON = 'monty-python';
20
+ export const IMAGE_STYLE_AUTO = 'auto';
21
+ export const IMAGE_STYLE_NONE = 'none';
@@ -19,7 +19,6 @@ declare const useImageGenerator: () => {
19
19
  userPrompt?: string;
20
20
  }) => Promise<ImageGenerationResponse>;
21
21
  generateImageWithParameters: (parameters: object) => Promise<ImageGenerationResponse>;
22
- getImageStyles: () => object;
23
22
  };
24
23
  export default useImageGenerator;
25
24
  export * from './constants.js';
@@ -7,7 +7,6 @@ import debugFactory from 'debug';
7
7
  */
8
8
  import askQuestionSync from '../../ask-question/sync.js';
9
9
  import requestJwt from '../../jwt/index.js';
10
- import { IMAGE_STYLE_LABELS } from './constants.js';
11
10
  const debug = debugFactory('ai-client:use-image-generator');
12
11
  /**
13
12
  * Cut the post content on a given lenght so the total length of the prompt is not longer than 4000 characters.
@@ -196,19 +195,10 @@ const useImageGenerator = () => {
196
195
  return Promise.reject(error);
197
196
  }
198
197
  };
199
- /**
200
- * Get available styles.
201
- *
202
- * @return {object} with the styles {key:label} for the image generation.
203
- */
204
- const getImageStyles = function () {
205
- return IMAGE_STYLE_LABELS;
206
- };
207
198
  return {
208
199
  generateImage,
209
200
  generateImageWithStableDiffusion,
210
201
  generateImageWithParameters: executeImageGeneration,
211
- getImageStyles,
212
202
  };
213
203
  };
214
204
  export default useImageGenerator;
@@ -29,7 +29,7 @@ import { UpgradeScreen } from './upgrade-screen.js';
29
29
  import { VisitSiteBanner } from './visit-site-banner.js';
30
30
  import './generator-modal.scss';
31
31
  const debug = debugFactory('jetpack-ai-calypso:generator-modal');
32
- export const GeneratorModal = ({ isOpen, onClose, onApplyLogo, onReload, siteDetails, context, placement, showStyleSelector, }) => {
32
+ export const GeneratorModal = ({ isOpen, onClose, onApplyLogo, onReload, siteDetails, context, placement, }) => {
33
33
  const { tracks } = useAnalytics();
34
34
  const { recordEvent: recordTracksEvent } = tracks;
35
35
  const { setSiteDetails, fetchAiAssistantFeature, loadLogoHistory, setIsLoadingHistory } = useDispatch(STORE_NAME);
@@ -40,7 +40,7 @@ export const GeneratorModal = ({ isOpen, onClose, onApplyLogo, onReload, siteDet
40
40
  const requestedFeatureData = useRef(false);
41
41
  const [needsFeature, setNeedsFeature] = useState(false);
42
42
  const [needsMoreRequests, setNeedsMoreRequests] = useState(false);
43
- const { selectedLogo, getAiAssistantFeature, generateFirstPrompt, generateLogo, setContext, tierPlansEnabled, } = useLogoGenerator();
43
+ const { selectedLogo, getAiAssistantFeature, generateFirstPrompt, generateLogo, setContext, tierPlansEnabled, site, requireUpgrade, } = useLogoGenerator();
44
44
  const { featureFetchError, firstLogoPromptFetchError, clearErrors } = useRequestErrors();
45
45
  const siteId = siteDetails?.ID;
46
46
  const [logoAccepted, setLogoAccepted] = useState(false);
@@ -73,9 +73,10 @@ export const GeneratorModal = ({ isOpen, onClose, onApplyLogo, onReload, siteDet
73
73
  const hasHistory = !isLogoHistoryEmpty(String(siteId));
74
74
  const logoCost = feature?.costs?.['jetpack-ai-logo-generator']?.logo ?? DEFAULT_LOGO_COST;
75
75
  const promptCreationCost = 1;
76
- const currentLimit = feature?.currentTier?.value || 0;
76
+ const currentLimit = feature?.currentTier?.limit || 0;
77
+ const currentValue = feature?.currentTier?.value || 0;
77
78
  const currentUsage = feature?.usagePeriod?.requestsCount || 0;
78
- const isUnlimited = !tierPlansEnabled ? currentLimit > 0 : currentLimit === 1;
79
+ const isUnlimited = !tierPlansEnabled ? currentValue > 0 : currentValue === 1;
79
80
  const hasNoNextTier = !feature?.nextTier; // If there is no next tier, the user cannot upgrade.
80
81
  // The user needs an upgrade immediately if they have no logos and not enough requests remaining for one prompt and one logo generation.
81
82
  const siteNeedsMoreRequests = !isUnlimited &&
@@ -96,13 +97,30 @@ export const GeneratorModal = ({ isOpen, onClose, onApplyLogo, onReload, siteDet
96
97
  await clearDeletedMedia(String(siteId));
97
98
  loadLogoHistory(siteId);
98
99
  // If there is any logo, we do not need to generate a first logo again.
99
- if (!isLogoHistoryEmpty(String(siteId))) {
100
+ if (hasHistory) {
100
101
  setLoadingState(null);
101
102
  setIsLoadingHistory(false);
102
103
  return;
103
104
  }
104
- // If the site does not require an upgrade and has no logos stored, generate the first prompt based on the site's data.
105
- generateFirstLogo();
105
+ // if site requires an upgrade, just return and set loaders to null,
106
+ // prompt component will take over the situation
107
+ if (requireUpgrade) {
108
+ setLoadingState(null);
109
+ setIsLoadingHistory(false);
110
+ return;
111
+ }
112
+ // If the site does not require an upgrade and has no logos stored
113
+ // and has title and description, generate the first prompt based on the site's data.
114
+ if (site &&
115
+ site.name &&
116
+ site.description &&
117
+ site.name !== __('Site Title', 'jetpack-ai-client')) {
118
+ generateFirstLogo();
119
+ }
120
+ else {
121
+ setLoadingState(null);
122
+ setIsLoadingHistory(false);
123
+ }
106
124
  }
107
125
  catch (error) {
108
126
  debug('Error fetching feature', error);
@@ -116,6 +134,7 @@ export const GeneratorModal = ({ isOpen, onClose, onApplyLogo, onReload, siteDet
116
134
  clearDeletedMedia,
117
135
  isLogoHistoryEmpty,
118
136
  siteId,
137
+ requireUpgrade,
119
138
  ]);
120
139
  const handleModalOpen = useCallback(async () => {
121
140
  setContext(context);
@@ -181,7 +200,7 @@ export const GeneratorModal = ({ isOpen, onClose, onApplyLogo, onReload, siteDet
181
200
  body = (_jsx(UpgradeScreen, { onCancel: closeModal, upgradeURL: upgradeURL, reason: needsFeature ? 'feature' : 'requests' }));
182
201
  }
183
202
  else {
184
- body = (_jsxs(_Fragment, { children: [!logoAccepted && (_jsx(Prompt, { initialPrompt: initialPrompt, showStyleSelector: showStyleSelector })), _jsx(LogoPresenter, { logo: selectedLogo, onApplyLogo: handleApplyLogo, logoAccepted: logoAccepted, siteId: String(siteId) }), logoAccepted ? (_jsxs("div", { className: "jetpack-ai-logo-generator__accept", children: [_jsx(VisitSiteBanner, {}), _jsx("div", { className: "jetpack-ai-logo-generator__accept-actions", children: _jsx(Button, { variant: "primary", onClick: closeModal, children: __('Close', 'jetpack-ai-client') }) })] })) : (_jsxs(_Fragment, { children: [_jsx(HistoryCarousel, {}), _jsx("div", { className: "jetpack-ai-logo-generator__footer", children: _jsxs(Button, { variant: "link", className: "jetpack-ai-logo-generator__feedback-button", href: "https://jetpack.com/redirect/?source=jetpack-ai-feedback", target: "_blank", onClick: handleFeedbackClick, children: [_jsx("span", { children: __('Provide feedback', 'jetpack-ai-client') }), _jsx(Icon, { icon: external, className: "icon" })] }) })] }))] }));
203
+ body = (_jsxs(_Fragment, { children: [!logoAccepted && _jsx(Prompt, { initialPrompt: initialPrompt }), _jsx(LogoPresenter, { logo: selectedLogo, onApplyLogo: handleApplyLogo, logoAccepted: logoAccepted, siteId: String(siteId) }), logoAccepted ? (_jsxs("div", { className: "jetpack-ai-logo-generator__accept", children: [_jsx(VisitSiteBanner, {}), _jsx("div", { className: "jetpack-ai-logo-generator__accept-actions", children: _jsx(Button, { variant: "primary", onClick: closeModal, children: __('Close', 'jetpack-ai-client') }) })] })) : (_jsxs(_Fragment, { children: [_jsx(HistoryCarousel, {}), _jsx("div", { className: "jetpack-ai-logo-generator__footer", children: _jsxs(Button, { variant: "link", className: "jetpack-ai-logo-generator__feedback-button", href: "https://jetpack.com/redirect/?source=jetpack-ai-feedback", target: "_blank", onClick: handleFeedbackClick, children: [_jsx("span", { children: __('Provide feedback', 'jetpack-ai-client') }), _jsx(Icon, { icon: external, className: "icon" })] }) })] }))] }));
185
204
  }
186
205
  return (_jsx(_Fragment, { children: isOpen && (_jsx(Modal, { className: "jetpack-ai-logo-generator-modal", onRequestClose: closeModal, shouldCloseOnClickOutside: false, shouldCloseOnEsc: false, title: __('Jetpack AI Logo Generator', 'jetpack-ai-client'), children: _jsx("div", { className: clsx('jetpack-ai-logo-generator-modal__body', {
187
206
  'notice-modal': needsFeature || needsMoreRequests || featureFetchError || firstLogoPromptFetchError,
@@ -31,7 +31,7 @@ export const HistoryCarousel = () => {
31
31
  }
32
32
  return thumbnailURL.toString();
33
33
  };
34
- return (_jsxs("div", { className: "jetpack-ai-logo-generator__carousel", children: [!logos.length && isLoadingHistory && (_jsx(Button, { disabled: true, className: clsx('jetpack-ai-logo-generator__carousel-logo'), children: _jsx("img", { height: "48", width: "48", src: loader, alt: 'loading' }) })), logos.map((logo, index) => (_jsx(Button, { className: clsx('jetpack-ai-logo-generator__carousel-logo', {
34
+ return (_jsxs("div", { className: "jetpack-ai-logo-generator__carousel", children: [!logos.length && isLoadingHistory && (_jsx(Button, { disabled: true, className: clsx('jetpack-ai-logo-generator__carousel-logo'), children: _jsx("img", { height: "48", width: "48", src: loader, alt: 'loading' }) })), !logos.length && !isLoadingHistory && _jsx("div", { children: "\u00A0" }), logos.map((logo, index) => (_jsx(Button, { className: clsx('jetpack-ai-logo-generator__carousel-logo', {
35
35
  'is-selected': logo.url === selectedLogo.url,
36
36
  }), onClick: () => handleClick(index), children: _jsx("img", { src: thumbnailFrom(logo.url), alt: logo.description }) }, logo.url)))] }));
37
37
  };
@@ -69,7 +69,7 @@ const UseOnSiteButton = ({ onApplyLogo, }) => {
69
69
  onApplyLogo?.(selectedLogo?.mediaId);
70
70
  }
71
71
  };
72
- return (_jsxs(Button, { className: "jetpack-ai-logo-generator-modal-presenter__action", onClick: handleClick, disabled: isSavingLogoToLibrary || !selectedLogo?.mediaId, children: [_jsx(Icon, { icon: _jsx(LogoIcon, {}) }), _jsx("span", { className: "action-text", children: __('Use on block', 'jetpack-ai-client') })] }));
72
+ return (_jsxs(Button, { className: "jetpack-ai-logo-generator-modal-presenter__action", onClick: handleClick, disabled: isSavingLogoToLibrary || !selectedLogo?.mediaId, variant: "secondary", children: [_jsx(Icon, { icon: _jsx(LogoIcon, {}) }), _jsx("span", { className: "action-text", children: __('Use on block', 'jetpack-ai-client') })] }));
73
73
  };
74
74
  const LogoLoading = () => {
75
75
  return (_jsxs(_Fragment, { children: [_jsx(ImageLoader, { className: "jetpack-ai-logo-generator-modal-presenter__logo" }), _jsx("span", { className: "jetpack-ai-logo-generator-modal-presenter__loading-text", children: __('Generating new logo…', 'jetpack-ai-client') })] }));
@@ -77,6 +77,9 @@ const LogoLoading = () => {
77
77
  const LogoFetching = () => {
78
78
  return (_jsxs(_Fragment, { children: [_jsx(ImageLoader, { className: "jetpack-ai-logo-generator-modal-presenter__logo" }), _jsx("span", { className: "jetpack-ai-logo-generator-modal-presenter__loading-text", children: __('Fetching previous logos…', 'jetpack-ai-client') })] }));
79
79
  };
80
+ const LogoEmpty = () => {
81
+ return (_jsxs(_Fragment, { children: [_jsx("div", { style: { width: 0, height: '229px' } }), _jsx("span", { className: "jetpack-ai-logo-generator-modal-presenter__loading-text", children: __('Once you generate a logo, it will show up here', 'jetpack-ai-client') })] }));
82
+ };
80
83
  const LogoReady = ({ siteId, logo, onApplyLogo }) => {
81
84
  return (_jsxs(_Fragment, { children: [_jsx("img", { src: logo.url, alt: logo.description, className: "jetpack-ai-logo-generator-modal-presenter__logo" }), _jsxs("div", { className: "jetpack-ai-logo-generator-modal-presenter__action-wrapper", children: [_jsx("span", { className: "jetpack-ai-logo-generator-modal-presenter__description", children: logo.description }), _jsxs("div", { className: "jetpack-ai-logo-generator-modal-presenter__actions", children: [_jsx(SaveInLibraryButton, { siteId: siteId }), _jsx(UseOnSiteButton, { onApplyLogo: onApplyLogo })] })] })] }));
82
85
  };
@@ -88,7 +91,10 @@ export const LogoPresenter = ({ logo = null, loading = false, onApplyLogo, logoA
88
91
  const { isRequestingImage } = useLogoGenerator();
89
92
  const { saveToLibraryError, logoUpdateError } = useRequestErrors();
90
93
  let logoContent;
91
- if (!logo) {
94
+ if (!logo && !isRequestingImage) {
95
+ logoContent = _jsx(LogoEmpty, {});
96
+ }
97
+ else if (!logo) {
92
98
  debug('No logo provided, history still loading or logo being generated');
93
99
  logoContent = _jsx(LogoFetching, {});
94
100
  }
@@ -0,0 +1,6 @@
1
+ import './prompt.scss';
2
+ type PromptProps = {
3
+ initialPrompt?: string;
4
+ };
5
+ export declare const Prompt: ({ initialPrompt }: PromptProps) => import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -11,9 +11,9 @@ import { useCallback, useEffect, useState, useRef } from 'react';
11
11
  /**
12
12
  * Internal dependencies
13
13
  */
14
- import { IMAGE_STYLE_MONTY_PYTHON, IMAGE_STYLE_LINE_ART, } from '../../hooks/use-image-generator/constants.js';
14
+ import { IMAGE_STYLE_NONE, IMAGE_STYLE_AUTO } from '../../hooks/use-image-generator/constants.js';
15
15
  import AiIcon from '../assets/icons/ai.js';
16
- import { EVENT_GENERATE, MINIMUM_PROMPT_LENGTH, EVENT_UPGRADE, EVENT_PLACEMENT_INPUT_FOOTER, EVENT_SWITCH_STYLE, } from '../constants.js';
16
+ import { EVENT_GENERATE, MINIMUM_PROMPT_LENGTH, EVENT_UPGRADE, EVENT_PLACEMENT_INPUT_FOOTER, EVENT_SWITCH_STYLE, EVENT_GUESS_STYLE, } from '../constants.js';
17
17
  import { useCheckout } from '../hooks/use-checkout.js';
18
18
  import useLogoGenerator from '../hooks/use-logo-generator.js';
19
19
  import useRequestErrors from '../hooks/use-request-errors.js';
@@ -21,7 +21,7 @@ import { FairUsageNotice } from './fair-usage-notice.js';
21
21
  import { UpgradeNudge } from './upgrade-nudge.js';
22
22
  import './prompt.scss';
23
23
  const debug = debugFactory('jetpack-ai-calypso:prompt-box');
24
- export const Prompt = ({ initialPrompt = '', showStyleSelector = false }) => {
24
+ export const Prompt = ({ initialPrompt = '' }) => {
25
25
  const { tracks } = useAnalytics();
26
26
  const { recordEvent: recordTracksEvent } = tracks;
27
27
  const [prompt, setPrompt] = useState(initialPrompt);
@@ -29,8 +29,10 @@ export const Prompt = ({ initialPrompt = '', showStyleSelector = false }) => {
29
29
  const { enhancePromptFetchError, logoFetchError } = useRequestErrors();
30
30
  const { nextTierCheckoutURL: checkoutUrl, hasNextTier } = useCheckout();
31
31
  const hasPrompt = prompt?.length >= MINIMUM_PROMPT_LENGTH;
32
- const [style, setStyle] = useState(showStyleSelector ? IMAGE_STYLE_LINE_ART : null);
33
- const { generateLogo, enhancePrompt, setIsEnhancingPrompt, isBusy, isEnhancingPrompt, site, getAiAssistantFeature, requireUpgrade, context, tierPlansEnabled, getImageStyles, } = useLogoGenerator();
32
+ const [showStyleSelector, setShowStyleSelector] = useState(false);
33
+ const [style, setStyle] = useState(null);
34
+ const [styles, setStyles] = useState([]);
35
+ const { generateLogo, enhancePrompt, setIsEnhancingPrompt, isBusy, isEnhancingPrompt, site, getAiAssistantFeature, requireUpgrade, context, tierPlansEnabled, imageStyles, guessStyle, } = useLogoGenerator();
34
36
  const enhancingLabel = __('Enhancing…', 'jetpack-ai-client');
35
37
  const enhanceLabel = __('Enhance prompt', 'jetpack-ai-client');
36
38
  const enhanceButtonLabel = isEnhancingPrompt ? enhancingLabel : enhanceLabel;
@@ -67,10 +69,39 @@ export const Prompt = ({ initialPrompt = '', showStyleSelector = false }) => {
67
69
  inputRef.current.textContent = prompt;
68
70
  }
69
71
  }, [prompt]);
72
+ useEffect(() => {
73
+ if (imageStyles.length > 0) {
74
+ // Sort styles to have "None" and "Auto" first
75
+ setStyles([
76
+ imageStyles.find(({ value }) => value === IMAGE_STYLE_NONE),
77
+ imageStyles.find(({ value }) => value === IMAGE_STYLE_AUTO),
78
+ ...imageStyles.filter(({ value }) => ![IMAGE_STYLE_NONE, IMAGE_STYLE_AUTO].includes(value)),
79
+ ].filter(v => v) // simplest way to get rid of empty values
80
+ );
81
+ setShowStyleSelector(true);
82
+ setStyle(IMAGE_STYLE_NONE);
83
+ }
84
+ else {
85
+ setStyles([]);
86
+ setShowStyleSelector(false);
87
+ setStyle(null);
88
+ }
89
+ }, [imageStyles]);
70
90
  const onGenerate = useCallback(async () => {
71
- // shouldn't tool be "logo-generator" to be more specific?
72
- recordTracksEvent(EVENT_GENERATE, { context, tool: 'image', style });
73
- generateLogo({ prompt, style });
91
+ debug(context);
92
+ if (style === IMAGE_STYLE_AUTO) {
93
+ setIsEnhancingPrompt(true);
94
+ recordTracksEvent(EVENT_GUESS_STYLE, { context, tool: 'image' });
95
+ const guessedStyle = (await guessStyle(prompt)) || IMAGE_STYLE_NONE;
96
+ setStyle(guessedStyle);
97
+ recordTracksEvent(EVENT_GENERATE, { context, tool: 'image', style: guessedStyle });
98
+ setIsEnhancingPrompt(false);
99
+ generateLogo({ prompt, style: guessedStyle });
100
+ }
101
+ else {
102
+ recordTracksEvent(EVENT_GENERATE, { context, tool: 'image', style });
103
+ generateLogo({ prompt, style });
104
+ }
74
105
  }, [context, generateLogo, prompt, style]);
75
106
  const onPromptInput = (event) => {
76
107
  setPrompt(event.target.textContent || '');
@@ -97,18 +128,15 @@ export const Prompt = ({ initialPrompt = '', showStyleSelector = false }) => {
97
128
  setStyle(imageStyle);
98
129
  recordTracksEvent(EVENT_SWITCH_STYLE, { context, style: imageStyle });
99
130
  }, [context, setStyle, recordTracksEvent]);
100
- const imageStyles = getImageStyles();
101
- const availableStyles = Object.keys(imageStyles).filter((styleKey) => styleKey !== IMAGE_STYLE_MONTY_PYTHON);
102
- return (_jsxs("div", { className: "jetpack-ai-logo-generator__prompt", children: [_jsxs("div", { className: "jetpack-ai-logo-generator__prompt-header", children: [_jsx("div", { className: "jetpack-ai-logo-generator__prompt-label", children: __('Describe your site:', 'jetpack-ai-client') }), _jsx("div", { className: "jetpack-ai-logo-generator__prompt-actions", children: _jsxs(Button, { variant: "link", disabled: isBusy || requireUpgrade || !hasPrompt, onClick: onEnhance, children: [_jsx(AiIcon, {}), enhanceButtonLabel] }) }), showStyleSelector && availableStyles && (_jsx(SelectControl
103
- // label={ __( 'Style', 'jetpack-ai-client' ) }
104
- , {
105
- // label={ __( 'Style', 'jetpack-ai-client' ) }
106
- __nextHasNoMarginBottom: true, value: style, options: availableStyles.map(imageStyle => ({
107
- label: imageStyles[imageStyle],
108
- value: imageStyle,
109
- })), onChange: updateStyle }))] }), _jsxs("div", { className: "jetpack-ai-logo-generator__prompt-query", children: [_jsx("div", { ref: inputRef, contentEditable: !isBusy && !requireUpgrade,
131
+ const onKeyDown = (event) => {
132
+ if (event.key === 'Enter') {
133
+ event.preventDefault();
134
+ onGenerate();
135
+ }
136
+ };
137
+ return (_jsxs("div", { className: "jetpack-ai-logo-generator__prompt", children: [_jsxs("div", { className: "jetpack-ai-logo-generator__prompt-header", children: [_jsx("div", { className: "jetpack-ai-logo-generator__prompt-label", children: __('Describe your site:', 'jetpack-ai-client') }), _jsx("div", { className: "jetpack-ai-logo-generator__prompt-actions", children: _jsxs(Button, { variant: "link", disabled: isBusy || requireUpgrade || !hasPrompt, onClick: onEnhance, children: [_jsx(AiIcon, {}), enhanceButtonLabel] }) }), showStyleSelector && (_jsx(SelectControl, { __nextHasNoMarginBottom: true, value: style, options: styles, onChange: updateStyle, disabled: isBusy || requireUpgrade }))] }), _jsxs("div", { className: "jetpack-ai-logo-generator__prompt-query", children: [_jsx("div", { role: "textbox", tabIndex: 0, ref: inputRef, contentEditable: !isBusy && !requireUpgrade,
110
138
  // The content editable div is expected to be updated by the enhance prompt, so warnings are suppressed
111
- suppressContentEditableWarning: true, className: "prompt-query__input", onInput: onPromptInput, onPaste: onPromptPaste, "data-placeholder": __('Describe your site or simply ask for a logo specifying some details about it', 'jetpack-ai-client') }), _jsx(Button, { variant: "primary", className: "jetpack-ai-logo-generator__prompt-submit", onClick: onGenerate, disabled: isBusy || requireUpgrade || !hasPrompt, children: __('Generate', 'jetpack-ai-client') })] }), _jsxs("div", { className: "jetpack-ai-logo-generator__prompt-footer", children: [!isUnlimited && !requireUpgrade && (_jsxs("div", { className: "jetpack-ai-logo-generator__prompt-requests", children: [_jsx("div", { children: sprintf(
139
+ suppressContentEditableWarning: true, className: "prompt-query__input", onInput: onPromptInput, onPaste: onPromptPaste, onKeyDown: onKeyDown, "data-placeholder": __('Describe your site or simply ask for a logo specifying some details about it', 'jetpack-ai-client') }), _jsx(Button, { variant: "primary", className: "jetpack-ai-logo-generator__prompt-submit", onClick: onGenerate, disabled: isBusy || requireUpgrade || !hasPrompt, children: __('Generate', 'jetpack-ai-client') })] }), _jsxs("div", { className: "jetpack-ai-logo-generator__prompt-footer", children: [!isUnlimited && !requireUpgrade && (_jsxs("div", { className: "jetpack-ai-logo-generator__prompt-requests", children: [_jsx("div", { children: sprintf(
112
140
  // translators: %u is the number of requests
113
141
  __('%u requests remaining.', 'jetpack-ai-client'), requestsRemaining) }), hasNextTier && (_jsxs(_Fragment, { children: ["\u00A0", _jsx(Button, { variant: "link", href: checkoutUrl, target: "_blank", onClick: onUpgradeClick, children: __('Upgrade', 'jetpack-ai-client') })] })), "\u00A0", _jsx(Tooltip, { text: __('Logo generation costs 10 requests; prompt enhancement costs 1 request each', 'jetpack-ai-client'), placement: "bottom", children: _jsx(Icon, { className: "prompt-footer__icon", icon: info }) })] })), requireUpgrade && tierPlansEnabled && _jsx(UpgradeNudge, {}), requireUpgrade && !tierPlansEnabled && _jsx(FairUsageNotice, {}), enhancePromptFetchError && (_jsx("div", { className: "jetpack-ai-logo-generator__prompt-error", children: __('Error enhancing prompt. Please try again.', 'jetpack-ai-client') })), logoFetchError && (_jsx("div", { className: "jetpack-ai-logo-generator__prompt-error", children: __('Error generating logo. Please try again.', 'jetpack-ai-client') }))] })] }));
114
142
  };
@@ -8,17 +8,21 @@ import { __ } from '@wordpress/i18n';
8
8
  /**
9
9
  * Internal dependencies
10
10
  */
11
+ import getRedirectUrl from '../../../../components/tools/jp-redirect/index.js';
11
12
  import { EVENT_PLACEMENT_FREE_USER_SCREEN, EVENT_UPGRADE } from '../constants.js';
12
13
  import useLogoGenerator from '../hooks/use-logo-generator.js';
13
14
  export const UpgradeScreen = ({ onCancel, upgradeURL, reason }) => {
14
15
  const { tracks } = useAnalytics();
15
16
  const { recordEvent: recordTracksEvent } = tracks;
16
- const upgradeMessageFeature = __('The logo generator requires a paid Jetpack AI plan. Upgrade your plan to access exclusive features, including logo generation. The upgrade will also increase the amount of requests you can use in all AI-powered features.', 'jetpack-ai-client');
17
+ const upgradeMessageFeature = __('Upgrade your Jetpack AI for access to logo generation. This upgrade will also increase the amount of monthly requests you can use in for all AI-powered features.', 'jetpack-ai-client');
17
18
  const upgradeMessageRequests = __('Not enough requests left to generate a logo. Upgrade your Jetpack AI to increase the amount of requests you can use in all AI-powered features.', 'jetpack-ai-client');
19
+ const upgradeInfoUrl = getRedirectUrl('ai-logo-generator-fair-usage-policy', {
20
+ anchor: 'usage-limitations-and-upgrades',
21
+ });
18
22
  const { context } = useLogoGenerator();
19
23
  const handleUpgradeClick = () => {
20
24
  recordTracksEvent(EVENT_UPGRADE, { context, placement: EVENT_PLACEMENT_FREE_USER_SCREEN });
21
25
  onCancel();
22
26
  };
23
- return (_jsxs("div", { className: "jetpack-ai-logo-generator-modal__notice-message-wrapper", children: [_jsxs("div", { className: "jetpack-ai-logo-generator-modal__notice-message", children: [_jsx("span", { className: "jetpack-ai-logo-generator-modal__loading-message", children: reason === 'feature' ? upgradeMessageFeature : upgradeMessageRequests }), "\u00A0", _jsx(Button, { variant: "link", href: "https://jetpack.com/ai/", target: "_blank", children: __('Learn more about Jetpack AI.', 'jetpack-ai-client') })] }), _jsxs("div", { className: "jetpack-ai-logo-generator-modal__notice-actions", children: [_jsx(Button, { variant: "tertiary", onClick: onCancel, children: __('Cancel', 'jetpack-ai-client') }), _jsx(Button, { variant: "primary", href: upgradeURL, target: "_blank", onClick: handleUpgradeClick, children: __('Upgrade', 'jetpack-ai-client') })] })] }));
27
+ return (_jsxs("div", { className: "jetpack-ai-logo-generator-modal__notice-message-wrapper", children: [_jsxs("div", { className: "jetpack-ai-logo-generator-modal__notice-message", children: [_jsx("span", { className: "jetpack-ai-logo-generator-modal__loading-message", children: reason === 'feature' ? upgradeMessageFeature : upgradeMessageRequests }), "\u00A0", _jsx(Button, { variant: "link", href: upgradeInfoUrl, target: "_blank", children: __('Learn more about Jetpack AI.', 'jetpack-ai-client') })] }), _jsxs("div", { className: "jetpack-ai-logo-generator-modal__notice-actions", children: [_jsx(Button, { variant: "tertiary", onClick: onCancel, children: __('Cancel', 'jetpack-ai-client') }), _jsx(Button, { variant: "primary", href: upgradeURL, target: "_blank", onClick: handleUpgradeClick, children: __('Upgrade', 'jetpack-ai-client') })] })] }));
24
28
  };
@@ -9,6 +9,7 @@ export declare const EVENT_NAVIGATE = "jetpack_ai_logo_generator_navigate";
9
9
  export declare const EVENT_FEEDBACK = "jetpack_ai_logo_generator_feedback";
10
10
  export declare const EVENT_UPGRADE = "jetpack_ai_upgrade_button";
11
11
  export declare const EVENT_SWITCH_STYLE = "jetpack_ai_logo_generator_switch_style";
12
+ export declare const EVENT_GUESS_STYLE = "jetpack_ai_logo_generator_guess_style";
12
13
  export declare const EVENT_PLACEMENT_QUICK_LINKS = "quick_links";
13
14
  export declare const EVENT_PLACEMENT_INPUT_FOOTER = "input_footer";
14
15
  export declare const EVENT_PLACEMENT_FREE_USER_SCREEN = "free_user_screen";
@@ -10,6 +10,7 @@ export const EVENT_NAVIGATE = 'jetpack_ai_logo_generator_navigate';
10
10
  export const EVENT_FEEDBACK = 'jetpack_ai_logo_generator_feedback';
11
11
  export const EVENT_UPGRADE = 'jetpack_ai_upgrade_button';
12
12
  export const EVENT_SWITCH_STYLE = 'jetpack_ai_logo_generator_switch_style';
13
+ export const EVENT_GUESS_STYLE = 'jetpack_ai_logo_generator_guess_style';
13
14
  // Event placement constants
14
15
  export const EVENT_PLACEMENT_QUICK_LINKS = 'quick_links';
15
16
  export const EVENT_PLACEMENT_INPUT_FOOTER = 'input_footer';
@@ -3,12 +3,10 @@
3
3
  */
4
4
  import { isAtomicSite, isSimpleSite, getSiteFragment, } from '@automattic/jetpack-shared-extension-utils';
5
5
  import { useSelect } from '@wordpress/data';
6
- import debugFactory from 'debug';
7
6
  /**
8
7
  * Internal dependencies
9
8
  */
10
9
  import { STORE_NAME } from '../store/index.js';
11
- const debug = debugFactory('ai-client:logo-generator:use-checkout');
12
10
  export const useCheckout = () => {
13
11
  const { nextTier, tierPlansEnabled } = useSelect(select => {
14
12
  const selectors = select(STORE_NAME);
@@ -38,7 +36,6 @@ export const useCheckout = () => {
38
36
  checkoutUrl.searchParams.set('query', `redirect_to=${encodeURIComponent(wpcomRedirectToURL)}`);
39
37
  }
40
38
  const nextTierCheckoutURL = checkoutUrl.toString();
41
- debug('Next tier checkout URL: ', nextTierCheckoutURL);
42
39
  return {
43
40
  nextTierCheckoutURL,
44
41
  hasNextTier: !!nextTier,
@@ -2,6 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useSelect } from '@wordpress/data';
3
3
  import { createInterpolateElement } from '@wordpress/element';
4
4
  import { __, sprintf } from '@wordpress/i18n';
5
+ import getRedirectUrl from '../../../../components/tools/jp-redirect/index.js';
5
6
  /**
6
7
  * Internal dependencies
7
8
  */
@@ -35,8 +36,11 @@ const useFairUsageNoticeMessage = () => {
35
36
  const nextUsagePeriodStartDateString = getFormattedUsagePeriodStartDate(usagePeriod);
36
37
  // Get the proper template based on the presence of the next usage period start date.
37
38
  const fairUsageNoticeMessage = getFairUsageNoticeMessage(nextUsagePeriodStartDateString);
39
+ const upgradeInfoUrl = getRedirectUrl('ai-logo-generator-fair-usage-policy', {
40
+ anchor: 'jetpack-ai-usage-limit',
41
+ });
38
42
  const fairUsageNoticeMessageElement = createInterpolateElement(fairUsageNoticeMessage, {
39
- link: (_jsx("a", { href: "https://jetpack.com/redirect/?source=ai-logo-generator-fair-usage-policy", target: "_blank", rel: "noreferrer" })),
43
+ link: _jsx("a", { href: upgradeInfoUrl, target: "_blank", rel: "noreferrer" }),
40
44
  });
41
45
  return fairUsageNoticeMessageElement;
42
46
  };
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Types
3
3
  */
4
- import type { ImageStyle } from '../../hooks/use-image-generator/constants.js';
4
+ import type { ImageStyle, ImageStyleObject } from '../../hooks/use-image-generator/constants.js';
5
5
  import type { Logo, SaveLogo } from '../store/types.js';
6
6
  declare const useLogoGenerator: () => {
7
7
  logos: Logo[];
@@ -48,6 +48,7 @@ declare const useLogoGenerator: () => {
48
48
  tierPlansEnabled: boolean;
49
49
  isLoadingHistory: boolean;
50
50
  setIsLoadingHistory: any;
51
- getImageStyles: () => object;
51
+ imageStyles: ImageStyleObject[];
52
+ guessStyle: (prompt: string) => Promise<ImageStyle | null>;
52
53
  };
53
54
  export default useLogoGenerator;
@@ -7,6 +7,7 @@ import { useCallback } from 'react';
7
7
  /**
8
8
  * Internal dependencies
9
9
  */
10
+ import askQuestionSync from '../../ask-question/sync.js';
10
11
  import useImageGenerator from '../../hooks/use-image-generator/index.js';
11
12
  import useSaveToMediaLibrary from '../../hooks/use-save-to-media-library/index.js';
12
13
  import requestJwt from '../../jwt/index.js';
@@ -37,12 +38,14 @@ const useLogoGenerator = () => {
37
38
  };
38
39
  }, []);
39
40
  const { setFirstLogoPromptFetchError, setEnhancePromptFetchError, setLogoFetchError, setSaveToLibraryError, setLogoUpdateError, } = useRequestErrors();
40
- const { generateImageWithParameters, getImageStyles } = useImageGenerator();
41
+ const { generateImageWithParameters } = useImageGenerator();
41
42
  const { saveToMediaLibrary } = useSaveToMediaLibrary();
42
43
  const { ID = null, name = null, description = null } = siteDetails || {};
43
44
  const siteId = ID ? String(ID) : null;
44
45
  const aiAssistantFeatureData = getAiAssistantFeature(siteId);
45
46
  const logoGenerationCost = aiAssistantFeatureData?.costs?.['jetpack-ai-logo-generator']?.logo;
47
+ const logoGeneratorControl = aiAssistantFeatureData?.featuresControl?.['logo-generator'];
48
+ const imageStyles = logoGeneratorControl?.styles;
46
49
  const generateFirstPrompt = useCallback(async function () {
47
50
  setFirstLogoPromptFetchError(null);
48
51
  increaseAiAssistantRequestsCount();
@@ -127,6 +130,38 @@ For example: user's prompt: A logo for an ice cream shop. Returned prompt: A log
127
130
  throw error;
128
131
  }
129
132
  };
133
+ const guessStyle = useCallback(async function (prompt) {
134
+ setLogoFetchError(null);
135
+ if (!imageStyles || !imageStyles.length) {
136
+ return null;
137
+ }
138
+ const messages = [
139
+ {
140
+ role: 'jetpack-ai',
141
+ context: {
142
+ type: 'ai-assistant-guess-logo-style',
143
+ request: prompt,
144
+ name,
145
+ description,
146
+ },
147
+ },
148
+ ];
149
+ try {
150
+ const style = await askQuestionSync(messages, { feature: 'jetpack-ai-logo-generator' });
151
+ if (!style) {
152
+ return null;
153
+ }
154
+ const styleObject = imageStyles.find(({ value }) => value === style);
155
+ if (!styleObject) {
156
+ return null;
157
+ }
158
+ return styleObject.value;
159
+ }
160
+ catch (error) {
161
+ debug('Error guessing style', error);
162
+ Promise.reject(error);
163
+ }
164
+ }, [imageStyles, name, description]);
130
165
  const generateImage = useCallback(async function ({ prompt, style = null, }) {
131
166
  setLogoFetchError(null);
132
167
  try {
@@ -134,6 +169,9 @@ For example: user's prompt: A logo for an ice cream shop. Returned prompt: A log
134
169
  if (!tokenData || !tokenData.token) {
135
170
  throw new Error('No token provided');
136
171
  }
172
+ if (style === 'auto') {
173
+ throw new Error('Auto style is not supported');
174
+ }
137
175
  debug('Generating image with prompt', prompt);
138
176
  const imageGenerationPrompt = `I NEED to test how the tool works with extremely simple prompts. DO NOT add any detail, just use it AS-IS:
139
177
  Create a single text-free iconic vector logo that symbolically represents the user request, using abstract or symbolic imagery.
@@ -146,6 +184,21 @@ The image should contain a single icon, without variations, color palettes or di
146
184
  User request:${prompt}`;
147
185
  const body = {
148
186
  prompt: imageGenerationPrompt,
187
+ // if style is set prompt is reworked at backend with messages
188
+ messages: style
189
+ ? [
190
+ {
191
+ role: 'jetpack-ai',
192
+ context: {
193
+ type: 'ai-assistant-generate-logo',
194
+ request: prompt,
195
+ name,
196
+ description,
197
+ style,
198
+ },
199
+ },
200
+ ]
201
+ : [],
149
202
  feature: 'jetpack-ai-logo-generator',
150
203
  response_format: 'b64_json',
151
204
  style: style || '', // backend expects an empty string if no style is provided
@@ -157,7 +210,7 @@ User request:${prompt}`;
157
210
  setLogoFetchError(error);
158
211
  throw error;
159
212
  }
160
- }, []);
213
+ }, [name, description]);
161
214
  const saveLogo = useCallback(async (logo) => {
162
215
  setSaveToLibraryError(null);
163
216
  try {
@@ -287,7 +340,8 @@ User request:${prompt}`;
287
340
  tierPlansEnabled,
288
341
  isLoadingHistory,
289
342
  setIsLoadingHistory,
290
- getImageStyles,
343
+ imageStyles,
344
+ guessStyle,
291
345
  };
292
346
  };
293
347
  export default useLogoGenerator;
@@ -15,7 +15,7 @@ export declare const ENDPOINT_AI_ASSISTANT_FEATURE = "/wpcom/v2/jetpack-ai/ai-as
15
15
  * New AI Assistant feature async request
16
16
  */
17
17
  export declare const FREE_PLAN_REQUESTS_LIMIT = 20;
18
- export declare const UNLIMITED_PLAN_REQUESTS_LIMIT = 999999999;
18
+ export declare const UNLIMITED_PLAN_REQUESTS_LIMIT = 3000;
19
19
  export declare const ASYNC_REQUEST_COUNTDOWN_INIT_VALUE = 3;
20
20
  export declare const NEW_ASYNC_REQUEST_TIMER_INTERVAL = 5000;
21
21
  export declare const ACTION_DECREASE_NEW_ASYNC_REQUEST_COUNTDOWN = "DECREASE_NEW_ASYNC_REQUEST_COUNTDOWN";
@@ -15,7 +15,7 @@ export const ENDPOINT_AI_ASSISTANT_FEATURE = '/wpcom/v2/jetpack-ai/ai-assistant-
15
15
  * New AI Assistant feature async request
16
16
  */
17
17
  export const FREE_PLAN_REQUESTS_LIMIT = 20;
18
- export const UNLIMITED_PLAN_REQUESTS_LIMIT = 999999999;
18
+ export const UNLIMITED_PLAN_REQUESTS_LIMIT = 3000;
19
19
  export const ASYNC_REQUEST_COUNTDOWN_INIT_VALUE = 3;
20
20
  export const NEW_ASYNC_REQUEST_TIMER_INTERVAL = 5000;
21
21
  export const ACTION_DECREASE_NEW_ASYNC_REQUEST_COUNTDOWN = 'DECREASE_NEW_ASYNC_REQUEST_COUNTDOWN';
@@ -32,6 +32,12 @@ const INITIAL_STATE = {
32
32
  asyncRequestTimerId: 0,
33
33
  isRequestingImage: false,
34
34
  },
35
+ featuresControl: {
36
+ 'logo-generator': {
37
+ enabled: false,
38
+ styles: [],
39
+ },
40
+ },
35
41
  },
36
42
  },
37
43
  history: [],