@automattic/jetpack-ai-client 0.16.4 → 0.17.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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,11 @@ 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.17.0] - 2024-09-02
9
+ ### Added
10
+ - AI Client: Add FeaturesControl to ai-assistant-feature response parsing. [#39168]
11
+ - Jetpack AI: Support fair usage messaging on the Extension AI Control component. [#39103]
12
+
8
13
  ## [0.16.4] - 2024-08-26
9
14
  ### Changed
10
15
  - Updated package dependencies. [#39004]
@@ -392,6 +397,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
392
397
  - Updated package dependencies. [#31659]
393
398
  - Updated package dependencies. [#31785]
394
399
 
400
+ [0.17.0]: https://github.com/Automattic/jetpack-ai-client/compare/v0.16.4...v0.17.0
395
401
  [0.16.4]: https://github.com/Automattic/jetpack-ai-client/compare/v0.16.3...v0.16.4
396
402
  [0.16.3]: https://github.com/Automattic/jetpack-ai-client/compare/v0.16.2...v0.16.3
397
403
  [0.16.2]: https://github.com/Automattic/jetpack-ai-client/compare/v0.16.1...v0.16.2
@@ -17,6 +17,7 @@ type ExtensionAIControlProps = {
17
17
  error?: RequestingErrorProps;
18
18
  requestsRemaining?: number;
19
19
  showUpgradeMessage?: boolean;
20
+ showFairUsageMessage?: boolean;
20
21
  upgradeUrl?: string;
21
22
  wrapperRef?: React.MutableRefObject<HTMLDivElement | null>;
22
23
  onChange?: (newValue: string) => void;
@@ -34,6 +35,6 @@ type ExtensionAIControlProps = {
34
35
  * @param {React.MutableRefObject} ref - Ref to the component
35
36
  * @return {ReactElement} Rendered component
36
37
  */
37
- export declare function ExtensionAIControl({ className, disabled, value, placeholder, showButtonLabels, isTransparent, state, showGuideLine, error, requestsRemaining, showUpgradeMessage, upgradeUrl, wrapperRef, onChange, onSend, onStop, onClose, onUndo, onUpgrade, onTryAgain, }: ExtensionAIControlProps, ref: React.MutableRefObject<HTMLInputElement>): ReactElement;
38
+ export declare function ExtensionAIControl({ className, disabled, value, placeholder, showButtonLabels, isTransparent, state, showGuideLine, error, requestsRemaining, showUpgradeMessage, showFairUsageMessage, upgradeUrl, wrapperRef, onChange, onSend, onStop, onClose, onUndo, onUpgrade, onTryAgain, }: ExtensionAIControlProps, ref: React.MutableRefObject<HTMLInputElement>): ReactElement;
38
39
  declare const _default: React.ForwardRefExoticComponent<ExtensionAIControlProps & React.RefAttributes<HTMLInputElement>>;
39
40
  export default _default;
@@ -11,7 +11,7 @@ import { forwardRef } from 'react';
11
11
  /**
12
12
  * Internal dependencies
13
13
  */
14
- import { GuidelineMessage, ErrorMessage, UpgradeMessage } from '../message/index.js';
14
+ import { GuidelineMessage, ErrorMessage, UpgradeMessage, FairUsageLimitMessage, } from '../message/index.js';
15
15
  import AIControl from './ai-control.js';
16
16
  import './style.scss';
17
17
  /**
@@ -21,7 +21,7 @@ import './style.scss';
21
21
  * @param {React.MutableRefObject} ref - Ref to the component
22
22
  * @return {ReactElement} Rendered component
23
23
  */
24
- export function ExtensionAIControl({ className, disabled = false, value = '', placeholder = '', showButtonLabels = true, isTransparent = false, state = 'init', showGuideLine = false, error, requestsRemaining, showUpgradeMessage = false, upgradeUrl, wrapperRef, onChange, onSend, onStop, onClose, onUndo, onUpgrade, onTryAgain, }, ref) {
24
+ export function ExtensionAIControl({ className, disabled = false, value = '', placeholder = '', showButtonLabels = true, isTransparent = false, state = 'init', showGuideLine = false, error, requestsRemaining, showUpgradeMessage = false, showFairUsageMessage = false, upgradeUrl, wrapperRef, onChange, onSend, onStop, onClose, onUndo, onUpgrade, onTryAgain, }, ref) {
25
25
  const loading = state === 'requesting' || state === 'suggesting';
26
26
  const [editRequest, setEditRequest] = useState(false);
27
27
  const [lastValue, setLastValue] = useState(value || null);
@@ -78,6 +78,9 @@ export function ExtensionAIControl({ className, disabled = false, value = '', pl
78
78
  if (error?.message) {
79
79
  message = (_jsx(ErrorMessage, { error: error.message, code: error.code, onTryAgainClick: tryAgainHandler, onUpgradeClick: upgradeHandler, upgradeUrl: upgradeUrl }));
80
80
  }
81
+ else if (showFairUsageMessage) {
82
+ message = _jsx(FairUsageLimitMessage, {});
83
+ }
81
84
  else if (showUpgradeMessage) {
82
85
  message = (_jsx(UpgradeMessage, { requestsRemaining: requestsRemaining, onUpgradeClick: upgradeHandler, upgradeUrl: upgradeUrl }));
83
86
  }
@@ -47,6 +47,12 @@ export default function Message({ severity, icon, showSidebarIcon, onSidebarIcon
47
47
  * @return {React.ReactElement } - Message component.
48
48
  */
49
49
  export declare function GuidelineMessage(): React.ReactElement;
50
+ /**
51
+ * React component to render a fair usage limit message.
52
+ *
53
+ * @return {React.ReactElement } - Message component.
54
+ */
55
+ export declare function FairUsageLimitMessage(): React.ReactElement;
50
56
  /**
51
57
  * React component to render an upgrade message for free tier users
52
58
  *
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  * External dependencies
4
4
  */
5
5
  import { ExternalLink, Button } from '@wordpress/components';
6
+ import { createInterpolateElement } from '@wordpress/element';
6
7
  import { __, sprintf } from '@wordpress/i18n';
7
8
  import { Icon, check, arrowRight } from '@wordpress/icons';
8
9
  import clsx from 'clsx';
@@ -45,6 +46,18 @@ export default function Message({ severity = MESSAGE_SEVERITY_INFO, icon = null,
45
46
  export function GuidelineMessage() {
46
47
  return (_jsxs(Message, { children: [_jsx("span", { children: __('AI-generated content could be inaccurate or biased.', 'jetpack-ai-client') }), _jsx(ExternalLink, { href: "https://automattic.com/ai-guidelines", children: __('Learn more', 'jetpack-ai-client') })] }));
47
48
  }
49
+ /**
50
+ * React component to render a fair usage limit message.
51
+ *
52
+ * @return {React.ReactElement } - Message component.
53
+ */
54
+ export function FairUsageLimitMessage() {
55
+ const message = __("You've reached this month's request limit, per our <link>fair usage policy</link>", 'jetpack-ai-client');
56
+ const element = createInterpolateElement(message, {
57
+ link: (_jsx(ExternalLink, { href: "https://jetpack.com/redirect/?source=ai-assistant-fair-usage-policy" })),
58
+ });
59
+ return _jsx(Message, { severity: MESSAGE_SEVERITY_WARNING, children: element });
60
+ }
48
61
  /**
49
62
  * React component to render an upgrade message for free tier users
50
63
  *
@@ -32,6 +32,7 @@ export function mapAiFeatureResponseToAiFeatureProps(response) {
32
32
  nextTier: response['next-tier'],
33
33
  tierPlansEnabled: !!response['tier-plans-enabled'],
34
34
  costs: response.costs,
35
+ featuresControl: response['features-control'],
35
36
  };
36
37
  }
37
38
  const actions = {
@@ -77,6 +77,7 @@ export default function reducer(state: LogoGeneratorStateProp, action: {
77
77
  logo: number;
78
78
  };
79
79
  };
80
+ featuresControl?: import("./types.js").FeaturesControl;
80
81
  _meta?: {
81
82
  isRequesting: boolean;
82
83
  asyncRequestCountdown: number;
@@ -53,6 +53,14 @@ export type TierProp = {
53
53
  export type TierLimitProp = TierUnlimitedProps['limit'] | TierFreeProps['limit'] | Tier100Props['limit'] | Tier200Props['limit'] | Tier500Props['limit'] | Tier750Props['limit'] | Tier1000Props['limit'];
54
54
  export type TierSlugProp = TierUnlimitedProps['slug'] | TierFreeProps['slug'] | Tier100Props['slug'] | Tier200Props['slug'] | Tier500Props['slug'] | Tier750Props['slug'] | Tier1000Props['slug'];
55
55
  export type TierValueProp = TierUnlimitedProps['value'] | TierFreeProps['value'] | Tier100Props['value'] | Tier200Props['value'] | Tier500Props['value'] | Tier750Props['value'] | Tier1000Props['value'];
56
+ export type FeatureControl = {
57
+ enabled: boolean;
58
+ 'min-jetpack-version': string;
59
+ [key: string]: FeatureControl | boolean | string;
60
+ };
61
+ export type FeaturesControl = {
62
+ [key: string]: FeatureControl;
63
+ };
56
64
  export type AiFeatureProps = {
57
65
  hasFeature: boolean;
58
66
  isOverLimit: boolean;
@@ -75,6 +83,7 @@ export type AiFeatureProps = {
75
83
  logo: number;
76
84
  };
77
85
  };
86
+ featuresControl?: FeaturesControl;
78
87
  };
79
88
  export type AiFeatureStateProps = AiFeatureProps & {
80
89
  _meta?: {
@@ -157,6 +166,7 @@ export type AiAssistantFeatureEndpointResponseProps = {
157
166
  logo: number;
158
167
  };
159
168
  };
169
+ 'features-control'?: FeaturesControl;
160
170
  };
161
171
  export type SaveLogo = (logo: Logo) => Promise<{
162
172
  mediaId: number;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@automattic/jetpack-ai-client",
4
- "version": "0.16.4",
4
+ "version": "0.17.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": {
@@ -10,7 +10,12 @@ import React, { forwardRef } from 'react';
10
10
  /**
11
11
  * Internal dependencies
12
12
  */
13
- import { GuidelineMessage, ErrorMessage, UpgradeMessage } from '../message/index.js';
13
+ import {
14
+ GuidelineMessage,
15
+ ErrorMessage,
16
+ UpgradeMessage,
17
+ FairUsageLimitMessage,
18
+ } from '../message/index.js';
14
19
  import AIControl from './ai-control.js';
15
20
  import './style.scss';
16
21
  /**
@@ -31,6 +36,7 @@ type ExtensionAIControlProps = {
31
36
  error?: RequestingErrorProps;
32
37
  requestsRemaining?: number;
33
38
  showUpgradeMessage?: boolean;
39
+ showFairUsageMessage?: boolean;
34
40
  upgradeUrl?: string;
35
41
  wrapperRef?: React.MutableRefObject< HTMLDivElement | null >;
36
42
  onChange?: ( newValue: string ) => void;
@@ -62,6 +68,7 @@ export function ExtensionAIControl(
62
68
  error,
63
69
  requestsRemaining,
64
70
  showUpgradeMessage = false,
71
+ showFairUsageMessage = false,
65
72
  upgradeUrl,
66
73
  wrapperRef,
67
74
  onChange,
@@ -215,6 +222,8 @@ export function ExtensionAIControl(
215
222
  upgradeUrl={ upgradeUrl }
216
223
  />
217
224
  );
225
+ } else if ( showFairUsageMessage ) {
226
+ message = <FairUsageLimitMessage />;
218
227
  } else if ( showUpgradeMessage ) {
219
228
  message = (
220
229
  <UpgradeMessage
@@ -2,6 +2,7 @@
2
2
  * External dependencies
3
3
  */
4
4
  import { ExternalLink, Button } from '@wordpress/components';
5
+ import { createInterpolateElement } from '@wordpress/element';
5
6
  import { __, sprintf } from '@wordpress/i18n';
6
7
  import { Icon, check, arrowRight } from '@wordpress/icons';
7
8
  import clsx from 'clsx';
@@ -114,6 +115,25 @@ export function GuidelineMessage(): React.ReactElement {
114
115
  );
115
116
  }
116
117
 
118
+ /**
119
+ * React component to render a fair usage limit message.
120
+ *
121
+ * @return {React.ReactElement } - Message component.
122
+ */
123
+ export function FairUsageLimitMessage(): React.ReactElement {
124
+ const message = __(
125
+ "You've reached this month's request limit, per our <link>fair usage policy</link>",
126
+ 'jetpack-ai-client'
127
+ );
128
+ const element = createInterpolateElement( message, {
129
+ link: (
130
+ <ExternalLink href="https://jetpack.com/redirect/?source=ai-assistant-fair-usage-policy" />
131
+ ),
132
+ } );
133
+
134
+ return <Message severity={ MESSAGE_SEVERITY_WARNING }>{ element }</Message>;
135
+ }
136
+
117
137
  /**
118
138
  * React component to render an upgrade message for free tier users
119
139
  *
@@ -64,6 +64,7 @@ export function mapAiFeatureResponseToAiFeatureProps(
64
64
  nextTier: response[ 'next-tier' ],
65
65
  tierPlansEnabled: !! response[ 'tier-plans-enabled' ],
66
66
  costs: response.costs,
67
+ featuresControl: response[ 'features-control' ],
67
68
  };
68
69
  }
69
70
 
@@ -88,6 +88,14 @@ export type TierValueProp =
88
88
  | Tier750Props[ 'value' ]
89
89
  | Tier1000Props[ 'value' ];
90
90
 
91
+ export type FeatureControl = {
92
+ enabled: boolean;
93
+ 'min-jetpack-version': string;
94
+ [ key: string ]: FeatureControl | boolean | string;
95
+ };
96
+
97
+ export type FeaturesControl = { [ key: string ]: FeatureControl };
98
+
91
99
  export type AiFeatureProps = {
92
100
  hasFeature: boolean;
93
101
  isOverLimit: boolean;
@@ -110,6 +118,7 @@ export type AiFeatureProps = {
110
118
  logo: number;
111
119
  };
112
120
  };
121
+ featuresControl?: FeaturesControl;
113
122
  };
114
123
 
115
124
  // Type used in the `wordpress-com/plans` store.
@@ -202,6 +211,7 @@ export type AiAssistantFeatureEndpointResponseProps = {
202
211
  logo: number;
203
212
  };
204
213
  };
214
+ 'features-control'?: FeaturesControl;
205
215
  };
206
216
 
207
217
  export type SaveLogo = ( logo: Logo ) => Promise< { mediaId: number; mediaURL: string } >;