@automattic/jetpack-ai-client 0.25.2 โ†’ 0.25.4

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 (41) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/build/ai-client/src/components/ai-control/block-ai-control.d.ts +2 -1
  3. package/build/ai-client/src/components/ai-control/block-ai-control.js +10 -2
  4. package/build/ai-client/src/components/ai-control/extension-ai-control.d.ts +3 -1
  5. package/build/ai-client/src/components/ai-control/extension-ai-control.js +9 -3
  6. package/build/ai-client/src/components/ai-feedback/index.d.ts +27 -0
  7. package/build/ai-client/src/components/ai-feedback/index.js +71 -0
  8. package/build/ai-client/src/components/index.d.ts +1 -0
  9. package/build/ai-client/src/components/index.js +1 -0
  10. package/build/ai-client/src/components/message/index.d.ts +15 -4
  11. package/build/ai-client/src/components/message/index.js +22 -5
  12. package/build/ai-client/src/constants.d.ts +106 -0
  13. package/build/ai-client/src/constants.js +113 -0
  14. package/build/ai-client/src/index.d.ts +1 -0
  15. package/build/ai-client/src/index.js +4 -0
  16. package/build/ai-client/src/libs/index.d.ts +1 -0
  17. package/build/ai-client/src/libs/index.js +1 -0
  18. package/build/ai-client/src/libs/map-action-to-human-text.d.ts +13 -0
  19. package/build/ai-client/src/libs/map-action-to-human-text.js +40 -0
  20. package/build/ai-client/src/logo-generator/components/logo-presenter.js +25 -1
  21. package/build/ai-client/src/logo-generator/hooks/use-logo-generator.js +3 -0
  22. package/build/ai-client/src/logo-generator/lib/logo-storage.d.ts +9 -8
  23. package/build/ai-client/src/logo-generator/lib/logo-storage.js +12 -8
  24. package/build/ai-client/src/logo-generator/store/types.d.ts +2 -0
  25. package/build/ai-client/src/logo-generator/types.d.ts +1 -0
  26. package/package.json +2 -1
  27. package/src/components/ai-control/block-ai-control.tsx +15 -1
  28. package/src/components/ai-control/extension-ai-control.tsx +18 -2
  29. package/src/components/ai-feedback/index.tsx +135 -0
  30. package/src/components/ai-feedback/style.scss +16 -0
  31. package/src/components/index.ts +1 -0
  32. package/src/components/message/index.tsx +45 -12
  33. package/src/constants.ts +116 -0
  34. package/src/index.ts +5 -0
  35. package/src/libs/index.ts +2 -0
  36. package/src/libs/map-action-to-human-text.ts +77 -0
  37. package/src/logo-generator/components/logo-presenter.tsx +41 -0
  38. package/src/logo-generator/hooks/use-logo-generator.ts +4 -0
  39. package/src/logo-generator/lib/logo-storage.ts +18 -8
  40. package/src/logo-generator/store/types.ts +2 -0
  41. package/src/logo-generator/types.ts +1 -0
@@ -0,0 +1,116 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+
6
+ // Mappings
7
+ export const LANGUAGE_MAP = {
8
+ en: {
9
+ label: __( 'English', 'jetpack-ai-client' ),
10
+ },
11
+ es: {
12
+ label: __( 'Spanish', 'jetpack-ai-client' ),
13
+ },
14
+ fr: {
15
+ label: __( 'French', 'jetpack-ai-client' ),
16
+ },
17
+ de: {
18
+ label: __( 'German', 'jetpack-ai-client' ),
19
+ },
20
+ it: {
21
+ label: __( 'Italian', 'jetpack-ai-client' ),
22
+ },
23
+ pt: {
24
+ label: __( 'Portuguese', 'jetpack-ai-client' ),
25
+ },
26
+ ru: {
27
+ label: __( 'Russian', 'jetpack-ai-client' ),
28
+ },
29
+ zh: {
30
+ label: __( 'Chinese', 'jetpack-ai-client' ),
31
+ },
32
+ ja: {
33
+ label: __( 'Japanese', 'jetpack-ai-client' ),
34
+ },
35
+ ar: {
36
+ label: __( 'Arabic', 'jetpack-ai-client' ),
37
+ },
38
+ hi: {
39
+ label: __( 'Hindi', 'jetpack-ai-client' ),
40
+ },
41
+ ko: {
42
+ label: __( 'Korean', 'jetpack-ai-client' ),
43
+ },
44
+ };
45
+ export const PROMPT_TONES_MAP = {
46
+ formal: {
47
+ label: __( 'Formal', 'jetpack-ai-client' ),
48
+ emoji: '๐ŸŽฉ',
49
+ },
50
+ informal: {
51
+ label: __( 'Informal', 'jetpack-ai-client' ),
52
+ emoji: '๐Ÿ˜Š',
53
+ },
54
+ optimistic: {
55
+ label: __( 'Optimistic', 'jetpack-ai-client' ),
56
+ emoji: '๐Ÿ˜ƒ',
57
+ },
58
+ humorous: {
59
+ label: __( 'Humorous', 'jetpack-ai-client' ),
60
+ emoji: '๐Ÿ˜‚',
61
+ },
62
+ serious: {
63
+ label: __( 'Serious', 'jetpack-ai-client' ),
64
+ emoji: '๐Ÿ˜',
65
+ },
66
+ skeptical: {
67
+ label: __( 'Skeptical', 'jetpack-ai-client' ),
68
+ emoji: '๐Ÿคจ',
69
+ },
70
+ empathetic: {
71
+ label: __( 'Empathetic', 'jetpack-ai-client' ),
72
+ emoji: '๐Ÿ’—',
73
+ },
74
+ confident: {
75
+ label: __( 'Confident', 'jetpack-ai-client' ),
76
+ emoji: '๐Ÿ˜Ž',
77
+ },
78
+ passionate: {
79
+ label: __( 'Passionate', 'jetpack-ai-client' ),
80
+ emoji: 'โค๏ธ',
81
+ },
82
+ provocative: {
83
+ label: __( 'Provocative', 'jetpack-ai-client' ),
84
+ emoji: '๐Ÿ”ฅ',
85
+ },
86
+ };
87
+
88
+ // Prompt types
89
+ export const PROMPT_TYPE_SUMMARY_BY_TITLE = 'titleSummary' as const;
90
+ export const PROMPT_TYPE_CONTINUE = 'continue' as const;
91
+ export const PROMPT_TYPE_SIMPLIFY = 'simplify' as const;
92
+ export const PROMPT_TYPE_CORRECT_SPELLING = 'correctSpelling' as const;
93
+ export const PROMPT_TYPE_GENERATE_TITLE = 'generateTitle' as const;
94
+ export const PROMPT_TYPE_MAKE_LONGER = 'makeLonger' as const;
95
+ export const PROMPT_TYPE_MAKE_SHORTER = 'makeShorter' as const;
96
+ export const PROMPT_TYPE_CHANGE_TONE = 'changeTone' as const;
97
+ export const PROMPT_TYPE_SUMMARIZE = 'summarize' as const;
98
+ export const PROMPT_TYPE_CHANGE_LANGUAGE = 'changeLanguage' as const;
99
+ export const PROMPT_TYPE_USER_PROMPT = 'userPrompt' as const;
100
+ export const PROMPT_TYPE_JETPACK_FORM_CUSTOM_PROMPT = 'jetpackFormCustomPrompt' as const;
101
+ export const PROMPT_TYPE_TRANSFORM_LIST_TO_TABLE = 'transformListToTable' as const;
102
+ export const PROMPT_TYPE_WRITE_POST_FROM_LIST = 'writePostFromList' as const;
103
+
104
+ // Human-readable labels
105
+ export const TRANSLATE_LABEL = __( 'Translate', 'jetpack-ai-client' );
106
+ export const TONE_LABEL = __( 'Change tone', 'jetpack-ai-client' );
107
+ export const CORRECT_SPELLING_LABEL = __( 'Correct spelling and grammar', 'jetpack-ai-client' );
108
+ export const SIMPLIFY_LABEL = __( 'Simplify', 'jetpack-ai-client' );
109
+ export const SUMMARIZE_LABEL = __( 'Summarize', 'jetpack-ai-client' );
110
+ export const MAKE_SHORTER_LABEL = __( 'Make shorter', 'jetpack-ai-client' );
111
+ export const MAKE_LONGER_LABEL = __( 'Expand', 'jetpack-ai-client' );
112
+ export const TURN_LIST_INTO_TABLE_LABEL = __( 'Turn list into a table', 'jetpack-ai-client' );
113
+ export const WRITE_POST_FROM_LIST_LABEL = __( 'Write a post from this list', 'jetpack-ai-client' );
114
+ export const GENERATE_TITLE_LABEL = __( 'Generate a post title', 'jetpack-ai-client' );
115
+ export const SUMMARY_BASED_ON_TITLE_LABEL = __( 'Summary based on title', 'jetpack-ai-client' );
116
+ export const CONTINUE_LABEL = __( 'Continue writing', 'jetpack-ai-client' );
package/src/index.ts CHANGED
@@ -43,6 +43,11 @@ export * from './types.js';
43
43
  */
44
44
  export * from './libs/index.js';
45
45
 
46
+ /*
47
+ * Constants
48
+ */
49
+ export * from './constants.js';
50
+
46
51
  /*
47
52
  * Logo Generator
48
53
  */
package/src/libs/index.ts CHANGED
@@ -7,3 +7,5 @@ export {
7
7
  } from './markdown/index.js';
8
8
 
9
9
  export type { RenderHTMLRules } from './markdown/index.js';
10
+
11
+ export { mapActionToHumanText } from './map-action-to-human-text.js';
@@ -0,0 +1,77 @@
1
+ import {
2
+ LANGUAGE_MAP,
3
+ PROMPT_TONES_MAP,
4
+ PROMPT_TYPE_CHANGE_LANGUAGE,
5
+ PROMPT_TYPE_CHANGE_TONE,
6
+ PROMPT_TYPE_CONTINUE,
7
+ PROMPT_TYPE_CORRECT_SPELLING,
8
+ PROMPT_TYPE_GENERATE_TITLE,
9
+ PROMPT_TYPE_MAKE_LONGER,
10
+ PROMPT_TYPE_MAKE_SHORTER,
11
+ PROMPT_TYPE_SIMPLIFY,
12
+ PROMPT_TYPE_SUMMARIZE,
13
+ PROMPT_TYPE_SUMMARY_BY_TITLE,
14
+ PROMPT_TYPE_TRANSFORM_LIST_TO_TABLE,
15
+ PROMPT_TYPE_WRITE_POST_FROM_LIST,
16
+ CONTINUE_LABEL,
17
+ CORRECT_SPELLING_LABEL,
18
+ GENERATE_TITLE_LABEL,
19
+ MAKE_LONGER_LABEL,
20
+ MAKE_SHORTER_LABEL,
21
+ SIMPLIFY_LABEL,
22
+ SUMMARIZE_LABEL,
23
+ SUMMARY_BASED_ON_TITLE_LABEL,
24
+ TONE_LABEL,
25
+ TRANSLATE_LABEL,
26
+ TURN_LIST_INTO_TABLE_LABEL,
27
+ WRITE_POST_FROM_LIST_LABEL,
28
+ } from '../constants.js';
29
+
30
+ type MapActionToHumanTextOptions = {
31
+ language?: string;
32
+ tone?: string;
33
+ };
34
+
35
+ /**
36
+ * Maps an action to a human-readable text.
37
+ *
38
+ * @param action - The action to map.
39
+ * @param options - The options for the mapping.
40
+ * @return {string} The human-readable text.
41
+ */
42
+ export function mapActionToHumanText(
43
+ action: string,
44
+ options: MapActionToHumanTextOptions = {}
45
+ ): string | null {
46
+ const { language, tone } = options;
47
+ const languageCode = language?.split( ' (' )[ 0 ];
48
+
49
+ switch ( action ) {
50
+ case PROMPT_TYPE_CHANGE_LANGUAGE:
51
+ return `${ TRANSLATE_LABEL }: ${ LANGUAGE_MAP[ languageCode ].label }`;
52
+ case PROMPT_TYPE_CHANGE_TONE:
53
+ return `${ TONE_LABEL }: ${ PROMPT_TONES_MAP[ tone ].label }`;
54
+ case PROMPT_TYPE_CORRECT_SPELLING:
55
+ return CORRECT_SPELLING_LABEL;
56
+ case PROMPT_TYPE_SIMPLIFY:
57
+ return SIMPLIFY_LABEL;
58
+ case PROMPT_TYPE_SUMMARIZE:
59
+ return SUMMARIZE_LABEL;
60
+ case PROMPT_TYPE_MAKE_LONGER:
61
+ return MAKE_LONGER_LABEL;
62
+ case PROMPT_TYPE_MAKE_SHORTER:
63
+ return MAKE_SHORTER_LABEL;
64
+ case PROMPT_TYPE_TRANSFORM_LIST_TO_TABLE:
65
+ return TURN_LIST_INTO_TABLE_LABEL;
66
+ case PROMPT_TYPE_WRITE_POST_FROM_LIST:
67
+ return WRITE_POST_FROM_LIST_LABEL;
68
+ case PROMPT_TYPE_GENERATE_TITLE:
69
+ return GENERATE_TITLE_LABEL;
70
+ case PROMPT_TYPE_SUMMARY_BY_TITLE:
71
+ return SUMMARY_BASED_ON_TITLE_LABEL;
72
+ case PROMPT_TYPE_CONTINUE:
73
+ return CONTINUE_LABEL;
74
+ default:
75
+ return null;
76
+ }
77
+ }
@@ -9,6 +9,7 @@ import debugFactory from 'debug';
9
9
  /**
10
10
  * Internal dependencies
11
11
  */
12
+ import AiFeedbackThumbs from '../../components/ai-feedback/index.js';
12
13
  import CheckIcon from '../assets/icons/check.js';
13
14
  import LogoIcon from '../assets/icons/logo.js';
14
15
  import MediaIcon from '../assets/icons/media.js';
@@ -152,11 +153,50 @@ const LogoEmpty: React.FC = () => {
152
153
  );
153
154
  };
154
155
 
156
+ const RateLogo: React.FC< {
157
+ disabled: boolean;
158
+ ratedItem: string;
159
+ onRate: ( rating: string ) => void;
160
+ } > = ( { disabled, ratedItem, onRate } ) => {
161
+ const { logos, selectedLogo } = useLogoGenerator();
162
+ const savedRatings = logos
163
+ .filter( logo => logo.rating )
164
+ .reduce( ( acc, logo ) => {
165
+ acc[ logo.url ] = logo.rating;
166
+ return acc;
167
+ }, {} );
168
+
169
+ return (
170
+ <AiFeedbackThumbs
171
+ disabled={ disabled }
172
+ ratedItem={ ratedItem }
173
+ feature="logo-generator"
174
+ savedRatings={ savedRatings }
175
+ options={ {
176
+ mediaLibraryId: selectedLogo.mediaId,
177
+ prompt: selectedLogo.description,
178
+ } }
179
+ onRate={ onRate }
180
+ />
181
+ );
182
+ };
183
+
155
184
  const LogoReady: React.FC< {
156
185
  siteId: string;
157
186
  logo: Logo;
158
187
  onApplyLogo: ( mediaId: number ) => void;
159
188
  } > = ( { siteId, logo, onApplyLogo } ) => {
189
+ const handleRateLogo = ( rating: string ) => {
190
+ // Update localStorage
191
+ updateLogo( {
192
+ siteId,
193
+ url: logo.url,
194
+ newUrl: logo.url,
195
+ mediaId: logo.mediaId,
196
+ rating,
197
+ } );
198
+ };
199
+
160
200
  return (
161
201
  <>
162
202
  <img
@@ -171,6 +211,7 @@ const LogoReady: React.FC< {
171
211
  <div className="jetpack-ai-logo-generator-modal-presenter__actions">
172
212
  <SaveInLibraryButton siteId={ siteId } />
173
213
  <UseOnSiteButton onApplyLogo={ onApplyLogo } />
214
+ <RateLogo ratedItem={ logo.url } disabled={ false } onRate={ handleRateLogo } />
174
215
  </div>
175
216
  </div>
176
217
  </>
@@ -412,10 +412,13 @@ User request:${ prompt }`;
412
412
  throw error;
413
413
  }
414
414
 
415
+ const revisedPrompt = image.data[ 0 ].revised_prompt || null;
416
+
415
417
  // response_format=url returns object with url, otherwise b64_json
416
418
  const logo: Logo = {
417
419
  url: 'data:image/png;base64,' + image.data[ 0 ].b64_json,
418
420
  description: prompt,
421
+ revisedPrompt,
419
422
  };
420
423
 
421
424
  try {
@@ -424,6 +427,7 @@ User request:${ prompt }`;
424
427
  url: savedLogo.mediaURL,
425
428
  description: prompt,
426
429
  mediaId: savedLogo.mediaId,
430
+ revisedPrompt,
427
431
  } );
428
432
  } catch ( error ) {
429
433
  storeLogo( logo );
@@ -10,21 +10,28 @@ const MAX_LOGOS = 10;
10
10
  /**
11
11
  * Add an entry to the site's logo history.
12
12
  *
13
- * @param {SaveToStorageProps} saveToStorageProps - The properties to save to storage
14
- * @param {SaveToStorageProps.siteId} saveToStorageProps.siteId - The site ID
15
- * @param {SaveToStorageProps.url} saveToStorageProps.url - The URL of the logo
16
- * @param {SaveToStorageProps.description} saveToStorageProps.description - The description of the logo, based on the prompt used to generate it
17
- * @param {SaveToStorageProps.mediaId} saveToStorageProps.mediaId - The media ID of the logo on the backend
18
- *
13
+ * @param {SaveToStorageProps} saveToStorageProps - The properties to save to storage
14
+ * @param {SaveToStorageProps.siteId} saveToStorageProps.siteId - The site ID
15
+ * @param {SaveToStorageProps.url} saveToStorageProps.url - The URL of the logo
16
+ * @param {SaveToStorageProps.description} saveToStorageProps.description - The description of the logo, based on the prompt used to generate it
17
+ * @param {SaveToStorageProps.mediaId} saveToStorageProps.mediaId - The media ID of the logo on the backend
18
+ * @param {SaveToStorageProps.revisedPrompt} saveToStorageProps.revisedPrompt - The revised prompt of the logo
19
19
  * @return {Logo} The logo that was saved
20
20
  */
21
- export function stashLogo( { siteId, url, description, mediaId }: SaveToStorageProps ) {
21
+ export function stashLogo( {
22
+ siteId,
23
+ url,
24
+ description,
25
+ mediaId,
26
+ revisedPrompt,
27
+ }: SaveToStorageProps ) {
22
28
  const storedContent = getSiteLogoHistory( siteId );
23
29
 
24
30
  const logo: Logo = {
25
31
  url,
26
32
  description,
27
33
  mediaId,
34
+ revisedPrompt,
28
35
  };
29
36
 
30
37
  storedContent.push( logo );
@@ -45,9 +52,10 @@ export function stashLogo( { siteId, url, description, mediaId }: SaveToStorageP
45
52
  * @param {UpdateInStorageProps.url} updateInStorageProps.url - The URL of the logo to update
46
53
  * @param {UpdateInStorageProps.newUrl} updateInStorageProps.newUrl - The new URL of the logo
47
54
  * @param {UpdateInStorageProps.mediaId} updateInStorageProps.mediaId - The new media ID of the logo
55
+ * @param {UpdateInStorageProps.rating} updateInStorageProps.rating - The new rating of the logo
48
56
  * @return {Logo} The logo that was updated
49
57
  */
50
- export function updateLogo( { siteId, url, newUrl, mediaId }: UpdateInStorageProps ) {
58
+ export function updateLogo( { siteId, url, newUrl, mediaId, rating }: UpdateInStorageProps ) {
51
59
  const storedContent = getSiteLogoHistory( siteId );
52
60
 
53
61
  const index = storedContent.findIndex( logo => logo.url === url );
@@ -55,6 +63,7 @@ export function updateLogo( { siteId, url, newUrl, mediaId }: UpdateInStoragePro
55
63
  if ( index > -1 ) {
56
64
  storedContent[ index ].url = newUrl;
57
65
  storedContent[ index ].mediaId = mediaId;
66
+ storedContent[ index ].rating = rating;
58
67
  }
59
68
 
60
69
  localStorage.setItem(
@@ -96,6 +105,7 @@ export function getSiteLogoHistory( siteId: string ) {
96
105
  url: logo.url,
97
106
  description: logo.description,
98
107
  mediaId: logo.mediaId,
108
+ rating: logo.rating,
99
109
  } ) );
100
110
 
101
111
  return storedContent;
@@ -140,6 +140,8 @@ export type Logo = {
140
140
  url: string;
141
141
  description: string;
142
142
  mediaId?: number;
143
+ rating?: string;
144
+ revisedPrompt?: string;
143
145
  };
144
146
 
145
147
  export type RequestError = string | Error | null;
@@ -92,6 +92,7 @@ export type UpdateInStorageProps = {
92
92
  url: Logo[ 'url' ];
93
93
  newUrl: Logo[ 'url' ];
94
94
  mediaId: Logo[ 'mediaId' ];
95
+ rating?: Logo[ 'rating' ];
95
96
  };
96
97
 
97
98
  export type RemoveFromStorageProps = {