@automattic/jetpack-ai-client 0.31.2 → 0.32.1
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 +17 -0
- package/build/chrome-ai/factory.js +23 -3
- package/build/chrome-ai/get-availability.d.ts +1 -1
- package/build/chrome-ai/get-availability.js +14 -4
- package/build/chrome-ai/suggestions.js +28 -0
- package/build/components/ai-image/hooks/use-site-type.js +2 -2
- package/build/hooks/use-ai-checkout/index.js +3 -2
- package/build/hooks/use-ai-suggestions/index.js +6 -0
- package/build/jwt/index.js +1 -1
- package/build/logo-generator/hooks/use-checkout.js +3 -2
- package/package.json +24 -22
- package/src/chrome-ai/factory.ts +26 -3
- package/src/chrome-ai/get-availability.ts +21 -5
- package/src/chrome-ai/suggestions.ts +31 -1
- package/src/components/ai-image/hooks/use-site-type.ts +2 -2
- package/src/hooks/use-ai-checkout/index.ts +2 -3
- package/src/hooks/use-ai-suggestions/index.ts +7 -0
- package/src/jwt/index.ts +1 -1
- package/src/logo-generator/hooks/use-checkout.ts +3 -6
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,21 @@ 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.32.1] - 2025-06-24
|
|
9
|
+
### Added
|
|
10
|
+
- Improve error handling on Chrome AI events. [#44048]
|
|
11
|
+
|
|
12
|
+
## [0.32.0] - 2025-06-23
|
|
13
|
+
### Changed
|
|
14
|
+
- AI Assistant: Add A/B test for Chrome AI API features. [#43690]
|
|
15
|
+
- Scripts: Change imports for hosting checks. [#43972]
|
|
16
|
+
- Update package dependencies. [#44020]
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- Fix Chrome experiment assignment group. [#44018]
|
|
20
|
+
- Fix async function call on Chrome experiment availability. [#44026]
|
|
21
|
+
- Invert feature flag check. [#44011]
|
|
22
|
+
|
|
8
23
|
## [0.31.2] - 2025-06-16
|
|
9
24
|
### Changed
|
|
10
25
|
- Update dependencies. [#43878]
|
|
@@ -635,6 +650,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
635
650
|
- AI Client: stop using smart document visibility handling on the fetchEventSource library, so it does not restart the completion when changing tabs. [#32004]
|
|
636
651
|
- Updated package dependencies. [#31468] [#31659] [#31785]
|
|
637
652
|
|
|
653
|
+
[0.32.1]: https://github.com/Automattic/jetpack-ai-client/compare/v0.32.0...v0.32.1
|
|
654
|
+
[0.32.0]: https://github.com/Automattic/jetpack-ai-client/compare/v0.31.2...v0.32.0
|
|
638
655
|
[0.31.2]: https://github.com/Automattic/jetpack-ai-client/compare/v0.31.1...v0.31.2
|
|
639
656
|
[0.31.1]: https://github.com/Automattic/jetpack-ai-client/compare/v0.31.0...v0.31.1
|
|
640
657
|
[0.31.0]: https://github.com/Automattic/jetpack-ai-client/compare/v0.30.0...v0.31.0
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import debugFactory from 'debug';
|
|
1
2
|
import { PROMPT_TYPE_CHANGE_LANGUAGE, PROMPT_TYPE_SUMMARIZE } from "../constants.js";
|
|
2
3
|
import { isChromeAIAvailable } from "./get-availability.js";
|
|
3
4
|
import ChromeAISuggestionsEventSource from "./suggestions.js";
|
|
5
|
+
const debug = debugFactory('ai-client:chrome-ai-factory');
|
|
4
6
|
/**
|
|
5
7
|
* This will return an instance of ChromeAISuggestionsEventSource or false.
|
|
6
8
|
*
|
|
@@ -8,7 +10,8 @@ import ChromeAISuggestionsEventSource from "./suggestions.js";
|
|
|
8
10
|
* @return ChromeAISuggestionsEventSource | bool
|
|
9
11
|
*/
|
|
10
12
|
export default async function ChromeAIFactory(promptArg) {
|
|
11
|
-
if (!isChromeAIAvailable()) {
|
|
13
|
+
if (!(await isChromeAIAvailable())) {
|
|
14
|
+
debug('Chrome AI is not available');
|
|
12
15
|
return false;
|
|
13
16
|
}
|
|
14
17
|
const context = {
|
|
@@ -18,6 +21,7 @@ export default async function ChromeAIFactory(promptArg) {
|
|
|
18
21
|
let promptType = '';
|
|
19
22
|
let tone = null;
|
|
20
23
|
let wordCount = null;
|
|
24
|
+
debug('promptArg', promptArg);
|
|
21
25
|
if (Array.isArray(promptArg)) {
|
|
22
26
|
for (let i = 0; i < promptArg.length; i++) {
|
|
23
27
|
const prompt = promptArg[i];
|
|
@@ -45,9 +49,11 @@ export default async function ChromeAIFactory(promptArg) {
|
|
|
45
49
|
}
|
|
46
50
|
}
|
|
47
51
|
}
|
|
52
|
+
debug('promptType', promptType);
|
|
48
53
|
// Early return if the prompt type is not supported.
|
|
49
54
|
if (!promptType.startsWith('ai-assistant-change-language') &&
|
|
50
55
|
!promptType.startsWith('ai-content-lens')) {
|
|
56
|
+
debug('promptType is not supported');
|
|
51
57
|
return false;
|
|
52
58
|
}
|
|
53
59
|
// If the languageDetector is not available, we can't use the translation or summary features—it's safer to fall back
|
|
@@ -55,14 +61,17 @@ export default async function ChromeAIFactory(promptArg) {
|
|
|
55
61
|
if (!('LanguageDetector' in self) ||
|
|
56
62
|
!self.LanguageDetector.create ||
|
|
57
63
|
!self.LanguageDetector.availability) {
|
|
64
|
+
debug('LanguageDetector is not available');
|
|
58
65
|
return false;
|
|
59
66
|
}
|
|
60
67
|
const languageDetectorAvailability = await self.LanguageDetector.availability();
|
|
61
68
|
if (languageDetectorAvailability === 'unavailable') {
|
|
69
|
+
debug('LanguageDetector is unavailable');
|
|
62
70
|
return false;
|
|
63
71
|
}
|
|
64
72
|
const detector = await self.LanguageDetector.create();
|
|
65
73
|
if (languageDetectorAvailability !== 'available') {
|
|
74
|
+
debug('awaiting detector ready');
|
|
66
75
|
await detector.ready;
|
|
67
76
|
}
|
|
68
77
|
if (promptType.startsWith('ai-assistant-change-language')) {
|
|
@@ -70,6 +79,7 @@ export default async function ChromeAIFactory(promptArg) {
|
|
|
70
79
|
if (!('Translator' in self) ||
|
|
71
80
|
!self.Translator.create ||
|
|
72
81
|
!self.Translator.availability) {
|
|
82
|
+
debug('Translator is not available');
|
|
73
83
|
return false;
|
|
74
84
|
}
|
|
75
85
|
const languageOpts = {
|
|
@@ -87,8 +97,11 @@ export default async function ChromeAIFactory(promptArg) {
|
|
|
87
97
|
break;
|
|
88
98
|
}
|
|
89
99
|
}
|
|
100
|
+
debug('languageOpts', languageOpts);
|
|
90
101
|
const translationAvailability = await self.Translator.availability(languageOpts);
|
|
102
|
+
debug('translationAvailability', translationAvailability);
|
|
91
103
|
if (translationAvailability === 'unavailable') {
|
|
104
|
+
debug('Translator is unavailable');
|
|
92
105
|
return false;
|
|
93
106
|
}
|
|
94
107
|
const chromeAI = new ChromeAISuggestionsEventSource({
|
|
@@ -100,11 +113,14 @@ export default async function ChromeAIFactory(promptArg) {
|
|
|
100
113
|
}
|
|
101
114
|
if (promptType.startsWith('ai-content-lens')) {
|
|
102
115
|
if (!('Summarizer' in self)) {
|
|
116
|
+
debug('Summarizer is not available');
|
|
103
117
|
return false;
|
|
104
118
|
}
|
|
105
119
|
if (context.language && context.language !== 'en (English)') {
|
|
120
|
+
debug('Summary is not English');
|
|
106
121
|
return false;
|
|
107
122
|
}
|
|
123
|
+
debug('awaiting detector detect');
|
|
108
124
|
const confidences = await detector.detect(context.content);
|
|
109
125
|
// if it doesn't look like the content is in English, we can't use the summary feature
|
|
110
126
|
for (const confidence of confidences) {
|
|
@@ -113,6 +129,7 @@ export default async function ChromeAIFactory(promptArg) {
|
|
|
113
129
|
// required for the translator to work at all, which is also
|
|
114
130
|
// why en is the default language.
|
|
115
131
|
if (confidence.confidence > 0.75 && confidence.detectedLanguage !== 'en') {
|
|
132
|
+
debug('Confidence for non-English content');
|
|
116
133
|
return false;
|
|
117
134
|
}
|
|
118
135
|
}
|
|
@@ -120,11 +137,14 @@ export default async function ChromeAIFactory(promptArg) {
|
|
|
120
137
|
tone: tone,
|
|
121
138
|
wordCount: wordCount,
|
|
122
139
|
};
|
|
123
|
-
|
|
140
|
+
debug('summaryOpts', summaryOpts);
|
|
141
|
+
const chromeAiEventSourceOpts = {
|
|
124
142
|
content: context.content,
|
|
125
143
|
promptType: PROMPT_TYPE_SUMMARIZE,
|
|
126
144
|
options: summaryOpts,
|
|
127
|
-
}
|
|
145
|
+
};
|
|
146
|
+
debug('chromeAiEventSourceOpts', chromeAiEventSourceOpts);
|
|
147
|
+
return new ChromeAISuggestionsEventSource(chromeAiEventSourceOpts);
|
|
128
148
|
}
|
|
129
149
|
return false;
|
|
130
150
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { initializeExPlat, loadExperimentAssignmentWithAuth } from '@automattic/jetpack-explat';
|
|
5
5
|
import { select } from '@wordpress/data';
|
|
6
|
+
import debugFactory from 'debug';
|
|
7
|
+
const debug = debugFactory('ai-client:chrome-ai-availability');
|
|
6
8
|
/**
|
|
7
9
|
* Get the AI Assistant feature.
|
|
8
10
|
*
|
|
@@ -17,9 +19,17 @@ function getAiAssistantFeature() {
|
|
|
17
19
|
*
|
|
18
20
|
* @return {boolean} Whether Chrome AI can be enabled.
|
|
19
21
|
*/
|
|
20
|
-
export function isChromeAIAvailable() {
|
|
22
|
+
export async function isChromeAIAvailable() {
|
|
21
23
|
const { featuresControl } = getAiAssistantFeature();
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
// Extra check if we want to control this via the feature flag for now
|
|
25
|
+
if (featuresControl?.['chrome-ai']?.enabled !== true) {
|
|
26
|
+
debug('feature is disabled for this site/user');
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
initializeExPlat();
|
|
30
|
+
debug('initialized explat');
|
|
31
|
+
const { variationName } = await loadExperimentAssignmentWithAuth('calypso_jetpack_ai_gemini_api_202503_v1');
|
|
32
|
+
debug('variationName', variationName);
|
|
33
|
+
return variationName === 'treatment';
|
|
24
34
|
}
|
|
25
35
|
export default isChromeAIAvailable;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import debugFactory from 'debug';
|
|
1
2
|
import { PROMPT_TYPE_CHANGE_LANGUAGE, PROMPT_TYPE_SUMMARIZE } from "../constants.js";
|
|
2
3
|
import { getErrorData } from "../hooks/use-ai-suggestions/index.js";
|
|
3
4
|
import { renderHTMLFromMarkdown, renderMarkdownFromHTML } from "../libs/markdown/index.js";
|
|
4
5
|
import { ERROR_RESPONSE, ERROR_NETWORK } from "../types.js";
|
|
6
|
+
const debug = debugFactory('ai-client:chrome-ai-suggestions');
|
|
5
7
|
export default class ChromeAISuggestionsEventSource extends EventTarget {
|
|
6
8
|
fullMessage;
|
|
7
9
|
fullFunctionCall;
|
|
@@ -20,6 +22,7 @@ export default class ChromeAISuggestionsEventSource extends EventTarget {
|
|
|
20
22
|
this.initSource(data);
|
|
21
23
|
}
|
|
22
24
|
initSource({ content, promptType, options = {}, }) {
|
|
25
|
+
debug('initSource', content, promptType, options);
|
|
23
26
|
if (promptType === PROMPT_TYPE_CHANGE_LANGUAGE) {
|
|
24
27
|
this.translate(content, options.targetLanguage, options.sourceLanguage);
|
|
25
28
|
}
|
|
@@ -32,6 +35,7 @@ export default class ChromeAISuggestionsEventSource extends EventTarget {
|
|
|
32
35
|
checkForUnclearPrompt() { }
|
|
33
36
|
processEvent(e) {
|
|
34
37
|
let data;
|
|
38
|
+
debug('processEvent', e);
|
|
35
39
|
try {
|
|
36
40
|
data = JSON.parse(e.data);
|
|
37
41
|
}
|
|
@@ -47,6 +51,7 @@ export default class ChromeAISuggestionsEventSource extends EventTarget {
|
|
|
47
51
|
}
|
|
48
52
|
}
|
|
49
53
|
processErrorEvent(e) {
|
|
54
|
+
debug('processErrorEvent', e);
|
|
50
55
|
// Dispatch a generic network error event
|
|
51
56
|
this.dispatchEvent(new CustomEvent(ERROR_NETWORK, { detail: e }));
|
|
52
57
|
this.dispatchEvent(new CustomEvent(ERROR_RESPONSE, {
|
|
@@ -58,11 +63,25 @@ export default class ChromeAISuggestionsEventSource extends EventTarget {
|
|
|
58
63
|
if (!('Translator' in self)) {
|
|
59
64
|
return;
|
|
60
65
|
}
|
|
66
|
+
const translatorAvailability = await self.Translator.availability({
|
|
67
|
+
sourceLanguage: source,
|
|
68
|
+
targetLanguage: target,
|
|
69
|
+
});
|
|
70
|
+
if (translatorAvailability === 'unavailable') {
|
|
71
|
+
debug('awaiting translator ready');
|
|
72
|
+
this.processErrorEvent({
|
|
73
|
+
message: 'Translator is unavailable',
|
|
74
|
+
});
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
61
77
|
const translator = await self.Translator.create({
|
|
62
78
|
sourceLanguage: source,
|
|
63
79
|
targetLanguage: target,
|
|
64
80
|
});
|
|
65
81
|
if (!translator) {
|
|
82
|
+
this.processErrorEvent({
|
|
83
|
+
message: 'Translator failed to initialize',
|
|
84
|
+
});
|
|
66
85
|
return;
|
|
67
86
|
}
|
|
68
87
|
try {
|
|
@@ -96,24 +115,32 @@ export default class ChromeAISuggestionsEventSource extends EventTarget {
|
|
|
96
115
|
}
|
|
97
116
|
// use the Chrome AI summarizer
|
|
98
117
|
async summarize(text, tone, wordCount) {
|
|
118
|
+
debug('summarize', text, tone, wordCount);
|
|
99
119
|
if (!('Summarizer' in self)) {
|
|
100
120
|
return;
|
|
101
121
|
}
|
|
102
122
|
const availability = await self.Summarizer.availability();
|
|
103
123
|
if (availability === 'unavailable') {
|
|
124
|
+
this.processErrorEvent({
|
|
125
|
+
data: { message: 'Summarizer is unavailable' },
|
|
126
|
+
});
|
|
104
127
|
return;
|
|
105
128
|
}
|
|
106
129
|
const summarizerOptions = this.getSummarizerOptions(tone, wordCount);
|
|
107
130
|
const summarizer = await self.Summarizer.create(summarizerOptions);
|
|
108
131
|
if (availability !== 'available') {
|
|
132
|
+
debug('awaiting summarizer ready');
|
|
109
133
|
await summarizer.ready;
|
|
110
134
|
}
|
|
111
135
|
try {
|
|
112
136
|
const context = `Write with a ${tone} tone.`;
|
|
137
|
+
debug('context', context);
|
|
113
138
|
let summary = await summarizer.summarize(text, { context: context });
|
|
139
|
+
debug('summary', summary);
|
|
114
140
|
wordCount = wordCount ?? 50;
|
|
115
141
|
// gemini-nano has a tendency to exceed the word count, so we need to check and summarize again if necessary
|
|
116
142
|
if (summary.split(' ').length > wordCount) {
|
|
143
|
+
debug('summary exceeds word count');
|
|
117
144
|
summary = await summarizer.summarize(summary, { context: context });
|
|
118
145
|
}
|
|
119
146
|
this.processEvent({
|
|
@@ -126,6 +153,7 @@ export default class ChromeAISuggestionsEventSource extends EventTarget {
|
|
|
126
153
|
});
|
|
127
154
|
}
|
|
128
155
|
catch (error) {
|
|
156
|
+
debug('error', error);
|
|
129
157
|
this.processErrorEvent(error);
|
|
130
158
|
}
|
|
131
159
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { isWoASite, isSimpleSite } from '@automattic/jetpack-script-data';
|
|
5
5
|
import { useState } from '@wordpress/element';
|
|
6
6
|
/**
|
|
7
7
|
* Hook to get the type of site.
|
|
@@ -10,7 +10,7 @@ import { useState } from '@wordpress/element';
|
|
|
10
10
|
*/
|
|
11
11
|
export default function useSiteType() {
|
|
12
12
|
const getSiteType = () => {
|
|
13
|
-
if (
|
|
13
|
+
if (isWoASite()) {
|
|
14
14
|
return 'atomic';
|
|
15
15
|
}
|
|
16
16
|
if (isSimpleSite()) {
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
4
|
import getRedirectUrl from '@automattic/jetpack-components/tools/jp-redirect';
|
|
5
|
-
import {
|
|
5
|
+
import { isWpcomPlatformSite, isSimpleSite } from '@automattic/jetpack-script-data';
|
|
6
|
+
import { getSiteFragment, useAutosaveAndRedirect, } from '@automattic/jetpack-shared-extension-utils';
|
|
6
7
|
import useAiFeature from "../use-ai-feature/index.js";
|
|
7
8
|
const getWPComRedirectToURL = () => {
|
|
8
9
|
const searchParams = new URLSearchParams(window.location.search);
|
|
@@ -31,7 +32,7 @@ export default function useAICheckout() {
|
|
|
31
32
|
site: getSiteFragment(),
|
|
32
33
|
path: 'jetpack_ai_yearly',
|
|
33
34
|
});
|
|
34
|
-
const checkoutUrl =
|
|
35
|
+
const checkoutUrl = isWpcomPlatformSite() ? wpcomCheckoutUrl : jetpackCheckoutUrl;
|
|
35
36
|
const { autosaveAndRedirect, isRedirecting } = useAutosaveAndRedirect(checkoutUrl);
|
|
36
37
|
return {
|
|
37
38
|
checkoutUrl,
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { useCallback, useEffect, useRef, useState } from '@wordpress/element';
|
|
5
5
|
import { __ } from '@wordpress/i18n';
|
|
6
|
+
import debugFactory from 'debug';
|
|
6
7
|
/**
|
|
7
8
|
* Internal dependencies
|
|
8
9
|
*/
|
|
9
10
|
import askQuestion from "../../ask-question/index.js";
|
|
10
11
|
import ChromeAIFactory from "../../chrome-ai/factory.js";
|
|
11
12
|
import { ERROR_CONTEXT_TOO_LARGE, ERROR_MODERATION, ERROR_NETWORK, ERROR_QUOTA_EXCEEDED, ERROR_SERVICE_UNAVAILABLE, ERROR_UNCLEAR_PROMPT, ERROR_RESPONSE, AI_MODEL_DEFAULT, AI_MODEL_GEMINI_NANO, } from "../../types.js";
|
|
13
|
+
const debug = debugFactory('ai-client:use-ai-suggestions');
|
|
12
14
|
/**
|
|
13
15
|
* Get the error data for a given error code.
|
|
14
16
|
*
|
|
@@ -91,8 +93,10 @@ export default function useAiSuggestions({ prompt, autoRequest = false, askQuest
|
|
|
91
93
|
* @return {void}
|
|
92
94
|
*/
|
|
93
95
|
const handleSuggestion = useCallback((event) => {
|
|
96
|
+
debug('handleSuggestion', event);
|
|
94
97
|
const partialSuggestion = removeLlamaArtifact(event?.detail);
|
|
95
98
|
if (!partialSuggestion) {
|
|
99
|
+
debug('no partial suggestion');
|
|
96
100
|
return;
|
|
97
101
|
}
|
|
98
102
|
setSuggestion(partialSuggestion);
|
|
@@ -138,6 +142,7 @@ export default function useAiSuggestions({ prompt, autoRequest = false, askQuest
|
|
|
138
142
|
setRequestingState('requesting');
|
|
139
143
|
// check if we can (or should) use Chrome AI
|
|
140
144
|
const chromeAI = await ChromeAIFactory(promptArg);
|
|
145
|
+
debug('chromeAI', chromeAI !== false);
|
|
141
146
|
if (chromeAI !== false) {
|
|
142
147
|
setModelAndRef(AI_MODEL_GEMINI_NANO);
|
|
143
148
|
eventSourceRef.current = chromeAI;
|
|
@@ -147,6 +152,7 @@ export default function useAiSuggestions({ prompt, autoRequest = false, askQuest
|
|
|
147
152
|
eventSourceRef.current = await askQuestion(promptArg, options);
|
|
148
153
|
}
|
|
149
154
|
if (!eventSourceRef?.current) {
|
|
155
|
+
debug('no event source');
|
|
150
156
|
return;
|
|
151
157
|
}
|
|
152
158
|
// Alias
|
package/build/jwt/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { isWpcomPlatformSite } from '@automattic/jetpack-script-data';
|
|
5
|
+
import { getSiteFragment } from '@automattic/jetpack-shared-extension-utils';
|
|
5
6
|
import { useSelect } from '@wordpress/data';
|
|
6
7
|
/**
|
|
7
8
|
* Internal dependencies
|
|
@@ -15,7 +16,7 @@ export const useCheckout = () => {
|
|
|
15
16
|
tierPlansEnabled: selectors.getAiAssistantFeature().tierPlansEnabled,
|
|
16
17
|
};
|
|
17
18
|
}, []);
|
|
18
|
-
const isJetpackSite = !
|
|
19
|
+
const isJetpackSite = !isWpcomPlatformSite();
|
|
19
20
|
const redirectSource = isJetpackSite
|
|
20
21
|
? 'jetpack-ai-upgrade-url-for-jetpack-sites'
|
|
21
22
|
: 'jetpack-ai-yearly-tier-upgrade-nudge';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"private": false,
|
|
3
3
|
"name": "@automattic/jetpack-ai-client",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.32.1",
|
|
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": {
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"@storybook/react": "8.6.7",
|
|
32
32
|
"@types/markdown-it": "14.1.2",
|
|
33
33
|
"@types/turndown": "5.0.5",
|
|
34
|
-
"jest": "
|
|
35
|
-
"jest-environment-jsdom": "
|
|
34
|
+
"jest": "30.0.0",
|
|
35
|
+
"jest-environment-jsdom": "30.0.0",
|
|
36
36
|
"storybook": "8.6.7",
|
|
37
37
|
"typescript": "5.8.3"
|
|
38
38
|
},
|
|
@@ -45,28 +45,30 @@
|
|
|
45
45
|
"main": "./build/index.js",
|
|
46
46
|
"types": "./build/index.d.ts",
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@automattic/jetpack-base-styles": "^1.0.
|
|
49
|
-
"@automattic/jetpack-components": "^1.1.
|
|
50
|
-
"@automattic/jetpack-connection": "^1.2.
|
|
51
|
-
"@automattic/jetpack-
|
|
48
|
+
"@automattic/jetpack-base-styles": "^1.0.1",
|
|
49
|
+
"@automattic/jetpack-components": "^1.1.6",
|
|
50
|
+
"@automattic/jetpack-connection": "^1.2.6",
|
|
51
|
+
"@automattic/jetpack-script-data": "^0.4.4",
|
|
52
|
+
"@automattic/jetpack-explat": "workspace:*",
|
|
53
|
+
"@automattic/jetpack-shared-extension-utils": "^1.2.1",
|
|
52
54
|
"@microsoft/fetch-event-source": "2.0.1",
|
|
53
|
-
"@types/jest": "
|
|
55
|
+
"@types/jest": "30.0.0",
|
|
54
56
|
"@types/react": "18.3.23",
|
|
55
57
|
"@types/wordpress__block-editor": "11.5.16",
|
|
56
|
-
"@wordpress/api-fetch": "7.
|
|
57
|
-
"@wordpress/base-styles": "6.
|
|
58
|
-
"@wordpress/blob": "4.
|
|
59
|
-
"@wordpress/
|
|
60
|
-
"@wordpress/
|
|
61
|
-
"@wordpress/components": "29.
|
|
62
|
-
"@wordpress/compose": "7.
|
|
63
|
-
"@wordpress/data": "10.
|
|
64
|
-
"@wordpress/editor": "14.
|
|
65
|
-
"@wordpress/element": "6.
|
|
66
|
-
"@wordpress/i18n": "5.
|
|
67
|
-
"@wordpress/icons": "10.
|
|
68
|
-
"@wordpress/primitives": "4.
|
|
69
|
-
"@wordpress/url": "4.
|
|
58
|
+
"@wordpress/api-fetch": "7.25.0",
|
|
59
|
+
"@wordpress/base-styles": "6.1.0",
|
|
60
|
+
"@wordpress/blob": "4.25.0",
|
|
61
|
+
"@wordpress/block-editor": "14.20.0",
|
|
62
|
+
"@wordpress/blocks": "14.14.0",
|
|
63
|
+
"@wordpress/components": "29.11.0",
|
|
64
|
+
"@wordpress/compose": "7.25.0",
|
|
65
|
+
"@wordpress/data": "10.25.0",
|
|
66
|
+
"@wordpress/editor": "14.25.0",
|
|
67
|
+
"@wordpress/element": "6.25.0",
|
|
68
|
+
"@wordpress/i18n": "5.25.0",
|
|
69
|
+
"@wordpress/icons": "10.25.0",
|
|
70
|
+
"@wordpress/primitives": "4.25.0",
|
|
71
|
+
"@wordpress/url": "4.25.0",
|
|
70
72
|
"clsx": "2.1.1",
|
|
71
73
|
"debug": "4.4.1",
|
|
72
74
|
"markdown-it": "14.1.0",
|
package/src/chrome-ai/factory.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import debugFactory from 'debug';
|
|
1
2
|
import { PROMPT_TYPE_CHANGE_LANGUAGE, PROMPT_TYPE_SUMMARIZE } from '../constants.ts';
|
|
2
3
|
import { PromptProp, PromptItemProps } from '../types.ts';
|
|
3
4
|
import { isChromeAIAvailable } from './get-availability.ts';
|
|
4
5
|
import ChromeAISuggestionsEventSource from './suggestions.ts';
|
|
5
6
|
|
|
7
|
+
const debug = debugFactory( 'ai-client:chrome-ai-factory' );
|
|
8
|
+
|
|
6
9
|
interface PromptContext {
|
|
7
10
|
type?: string;
|
|
8
11
|
content?: string;
|
|
@@ -18,7 +21,8 @@ interface PromptContext {
|
|
|
18
21
|
* @return ChromeAISuggestionsEventSource | bool
|
|
19
22
|
*/
|
|
20
23
|
export default async function ChromeAIFactory( promptArg: PromptProp ) {
|
|
21
|
-
if ( ! isChromeAIAvailable() ) {
|
|
24
|
+
if ( ! ( await isChromeAIAvailable() ) ) {
|
|
25
|
+
debug( 'Chrome AI is not available' );
|
|
22
26
|
return false;
|
|
23
27
|
}
|
|
24
28
|
|
|
@@ -31,6 +35,7 @@ export default async function ChromeAIFactory( promptArg: PromptProp ) {
|
|
|
31
35
|
let tone = null;
|
|
32
36
|
let wordCount = null;
|
|
33
37
|
|
|
38
|
+
debug( 'promptArg', promptArg );
|
|
34
39
|
if ( Array.isArray( promptArg ) ) {
|
|
35
40
|
for ( let i = 0; i < promptArg.length; i++ ) {
|
|
36
41
|
const prompt: PromptItemProps = promptArg[ i ];
|
|
@@ -66,11 +71,13 @@ export default async function ChromeAIFactory( promptArg: PromptProp ) {
|
|
|
66
71
|
}
|
|
67
72
|
}
|
|
68
73
|
|
|
74
|
+
debug( 'promptType', promptType );
|
|
69
75
|
// Early return if the prompt type is not supported.
|
|
70
76
|
if (
|
|
71
77
|
! promptType.startsWith( 'ai-assistant-change-language' ) &&
|
|
72
78
|
! promptType.startsWith( 'ai-content-lens' )
|
|
73
79
|
) {
|
|
80
|
+
debug( 'promptType is not supported' );
|
|
74
81
|
return false;
|
|
75
82
|
}
|
|
76
83
|
|
|
@@ -81,16 +88,19 @@ export default async function ChromeAIFactory( promptArg: PromptProp ) {
|
|
|
81
88
|
! self.LanguageDetector.create ||
|
|
82
89
|
! self.LanguageDetector.availability
|
|
83
90
|
) {
|
|
91
|
+
debug( 'LanguageDetector is not available' );
|
|
84
92
|
return false;
|
|
85
93
|
}
|
|
86
94
|
|
|
87
95
|
const languageDetectorAvailability = await self.LanguageDetector.availability();
|
|
88
96
|
if ( languageDetectorAvailability === 'unavailable' ) {
|
|
97
|
+
debug( 'LanguageDetector is unavailable' );
|
|
89
98
|
return false;
|
|
90
99
|
}
|
|
91
100
|
|
|
92
101
|
const detector = await self.LanguageDetector.create();
|
|
93
102
|
if ( languageDetectorAvailability !== 'available' ) {
|
|
103
|
+
debug( 'awaiting detector ready' );
|
|
94
104
|
await detector.ready;
|
|
95
105
|
}
|
|
96
106
|
|
|
@@ -102,6 +112,7 @@ export default async function ChromeAIFactory( promptArg: PromptProp ) {
|
|
|
102
112
|
! self.Translator.create ||
|
|
103
113
|
! self.Translator.availability
|
|
104
114
|
) {
|
|
115
|
+
debug( 'Translator is not available' );
|
|
105
116
|
return false;
|
|
106
117
|
}
|
|
107
118
|
|
|
@@ -123,9 +134,12 @@ export default async function ChromeAIFactory( promptArg: PromptProp ) {
|
|
|
123
134
|
}
|
|
124
135
|
}
|
|
125
136
|
|
|
137
|
+
debug( 'languageOpts', languageOpts );
|
|
126
138
|
const translationAvailability = await self.Translator.availability( languageOpts );
|
|
127
139
|
|
|
140
|
+
debug( 'translationAvailability', translationAvailability );
|
|
128
141
|
if ( translationAvailability === 'unavailable' ) {
|
|
142
|
+
debug( 'Translator is unavailable' );
|
|
129
143
|
return false;
|
|
130
144
|
}
|
|
131
145
|
|
|
@@ -140,13 +154,16 @@ export default async function ChromeAIFactory( promptArg: PromptProp ) {
|
|
|
140
154
|
|
|
141
155
|
if ( promptType.startsWith( 'ai-content-lens' ) ) {
|
|
142
156
|
if ( ! ( 'Summarizer' in self ) ) {
|
|
157
|
+
debug( 'Summarizer is not available' );
|
|
143
158
|
return false;
|
|
144
159
|
}
|
|
145
160
|
|
|
146
161
|
if ( context.language && context.language !== 'en (English)' ) {
|
|
162
|
+
debug( 'Summary is not English' );
|
|
147
163
|
return false;
|
|
148
164
|
}
|
|
149
165
|
|
|
166
|
+
debug( 'awaiting detector detect' );
|
|
150
167
|
const confidences = await detector.detect( context.content );
|
|
151
168
|
|
|
152
169
|
// if it doesn't look like the content is in English, we can't use the summary feature
|
|
@@ -156,6 +173,7 @@ export default async function ChromeAIFactory( promptArg: PromptProp ) {
|
|
|
156
173
|
// required for the translator to work at all, which is also
|
|
157
174
|
// why en is the default language.
|
|
158
175
|
if ( confidence.confidence > 0.75 && confidence.detectedLanguage !== 'en' ) {
|
|
176
|
+
debug( 'Confidence for non-English content' );
|
|
159
177
|
return false;
|
|
160
178
|
}
|
|
161
179
|
}
|
|
@@ -165,11 +183,16 @@ export default async function ChromeAIFactory( promptArg: PromptProp ) {
|
|
|
165
183
|
wordCount: wordCount,
|
|
166
184
|
};
|
|
167
185
|
|
|
168
|
-
|
|
186
|
+
debug( 'summaryOpts', summaryOpts );
|
|
187
|
+
|
|
188
|
+
const chromeAiEventSourceOpts = {
|
|
169
189
|
content: context.content,
|
|
170
190
|
promptType: PROMPT_TYPE_SUMMARIZE,
|
|
171
191
|
options: summaryOpts,
|
|
172
|
-
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
debug( 'chromeAiEventSourceOpts', chromeAiEventSourceOpts );
|
|
195
|
+
return new ChromeAISuggestionsEventSource( chromeAiEventSourceOpts );
|
|
173
196
|
}
|
|
174
197
|
|
|
175
198
|
return false;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { initializeExPlat, loadExperimentAssignmentWithAuth } from '@automattic/jetpack-explat';
|
|
5
5
|
import { select } from '@wordpress/data';
|
|
6
|
+
import debugFactory from 'debug';
|
|
7
|
+
|
|
8
|
+
const debug = debugFactory( 'ai-client:chrome-ai-availability' );
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
* Types
|
|
@@ -33,12 +36,25 @@ function getAiAssistantFeature() {
|
|
|
33
36
|
*
|
|
34
37
|
* @return {boolean} Whether Chrome AI can be enabled.
|
|
35
38
|
*/
|
|
36
|
-
export function isChromeAIAvailable() {
|
|
39
|
+
export async function isChromeAIAvailable() {
|
|
37
40
|
const { featuresControl } = getAiAssistantFeature();
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
|
|
42
|
+
// Extra check if we want to control this via the feature flag for now
|
|
43
|
+
if ( featuresControl?.[ 'chrome-ai' ]?.enabled !== true ) {
|
|
44
|
+
debug( 'feature is disabled for this site/user' );
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
initializeExPlat();
|
|
49
|
+
debug( 'initialized explat' );
|
|
50
|
+
|
|
51
|
+
const { variationName } = await loadExperimentAssignmentWithAuth(
|
|
52
|
+
'calypso_jetpack_ai_gemini_api_202503_v1'
|
|
41
53
|
);
|
|
54
|
+
|
|
55
|
+
debug( 'variationName', variationName );
|
|
56
|
+
|
|
57
|
+
return variationName === 'treatment';
|
|
42
58
|
}
|
|
43
59
|
|
|
44
60
|
export default isChromeAIAvailable;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { EventSourceMessage } from '@microsoft/fetch-event-source';
|
|
2
|
+
import debugFactory from 'debug';
|
|
2
3
|
import { PROMPT_TYPE_CHANGE_LANGUAGE, PROMPT_TYPE_SUMMARIZE } from '../constants.ts';
|
|
3
4
|
import { getErrorData } from '../hooks/use-ai-suggestions/index.ts';
|
|
4
5
|
import { renderHTMLFromMarkdown, renderMarkdownFromHTML } from '../libs/markdown/index.ts';
|
|
@@ -36,6 +37,8 @@ type FunctionCallProps = {
|
|
|
36
37
|
arguments?: string;
|
|
37
38
|
};
|
|
38
39
|
|
|
40
|
+
const debug = debugFactory( 'ai-client:chrome-ai-suggestions' );
|
|
41
|
+
|
|
39
42
|
export default class ChromeAISuggestionsEventSource extends EventTarget {
|
|
40
43
|
fullMessage: string;
|
|
41
44
|
fullFunctionCall: FunctionCallProps;
|
|
@@ -63,6 +66,7 @@ export default class ChromeAISuggestionsEventSource extends EventTarget {
|
|
|
63
66
|
promptType,
|
|
64
67
|
options = {},
|
|
65
68
|
}: ChromeAISuggestionsEventSourceConstructorArgs ) {
|
|
69
|
+
debug( 'initSource', content, promptType, options );
|
|
66
70
|
if ( promptType === PROMPT_TYPE_CHANGE_LANGUAGE ) {
|
|
67
71
|
this.translate( content, options.targetLanguage, options.sourceLanguage );
|
|
68
72
|
}
|
|
@@ -80,6 +84,7 @@ export default class ChromeAISuggestionsEventSource extends EventTarget {
|
|
|
80
84
|
|
|
81
85
|
processEvent( e: EventSourceMessage ) {
|
|
82
86
|
let data: ChromeAIEvent;
|
|
87
|
+
debug( 'processEvent', e );
|
|
83
88
|
try {
|
|
84
89
|
data = JSON.parse( e.data );
|
|
85
90
|
} catch ( err ) {
|
|
@@ -99,6 +104,7 @@ export default class ChromeAISuggestionsEventSource extends EventTarget {
|
|
|
99
104
|
}
|
|
100
105
|
|
|
101
106
|
processErrorEvent( e ) {
|
|
107
|
+
debug( 'processErrorEvent', e );
|
|
102
108
|
// Dispatch a generic network error event
|
|
103
109
|
this.dispatchEvent( new CustomEvent( ERROR_NETWORK, { detail: e } ) );
|
|
104
110
|
this.dispatchEvent(
|
|
@@ -114,12 +120,28 @@ export default class ChromeAISuggestionsEventSource extends EventTarget {
|
|
|
114
120
|
return;
|
|
115
121
|
}
|
|
116
122
|
|
|
123
|
+
const translatorAvailability = await self.Translator.availability( {
|
|
124
|
+
sourceLanguage: source,
|
|
125
|
+
targetLanguage: target,
|
|
126
|
+
} );
|
|
127
|
+
|
|
128
|
+
if ( translatorAvailability === 'unavailable' ) {
|
|
129
|
+
debug( 'awaiting translator ready' );
|
|
130
|
+
this.processErrorEvent( {
|
|
131
|
+
message: 'Translator is unavailable',
|
|
132
|
+
} );
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
117
136
|
const translator = await self.Translator.create( {
|
|
118
137
|
sourceLanguage: source,
|
|
119
138
|
targetLanguage: target,
|
|
120
139
|
} );
|
|
121
140
|
|
|
122
141
|
if ( ! translator ) {
|
|
142
|
+
this.processErrorEvent( {
|
|
143
|
+
message: 'Translator failed to initialize',
|
|
144
|
+
} );
|
|
123
145
|
return;
|
|
124
146
|
}
|
|
125
147
|
|
|
@@ -161,6 +183,7 @@ export default class ChromeAISuggestionsEventSource extends EventTarget {
|
|
|
161
183
|
|
|
162
184
|
// use the Chrome AI summarizer
|
|
163
185
|
async summarize( text: string, tone?: string, wordCount?: number ) {
|
|
186
|
+
debug( 'summarize', text, tone, wordCount );
|
|
164
187
|
if ( ! ( 'Summarizer' in self ) ) {
|
|
165
188
|
return;
|
|
166
189
|
}
|
|
@@ -168,6 +191,9 @@ export default class ChromeAISuggestionsEventSource extends EventTarget {
|
|
|
168
191
|
const availability = await self.Summarizer.availability();
|
|
169
192
|
|
|
170
193
|
if ( availability === 'unavailable' ) {
|
|
194
|
+
this.processErrorEvent( {
|
|
195
|
+
data: { message: 'Summarizer is unavailable' },
|
|
196
|
+
} );
|
|
171
197
|
return;
|
|
172
198
|
}
|
|
173
199
|
|
|
@@ -176,17 +202,20 @@ export default class ChromeAISuggestionsEventSource extends EventTarget {
|
|
|
176
202
|
const summarizer = await self.Summarizer.create( summarizerOptions );
|
|
177
203
|
|
|
178
204
|
if ( availability !== 'available' ) {
|
|
205
|
+
debug( 'awaiting summarizer ready' );
|
|
179
206
|
await summarizer.ready;
|
|
180
207
|
}
|
|
181
208
|
|
|
182
209
|
try {
|
|
183
210
|
const context = `Write with a ${ tone } tone.`;
|
|
211
|
+
debug( 'context', context );
|
|
184
212
|
let summary = await summarizer.summarize( text, { context: context } );
|
|
185
|
-
|
|
213
|
+
debug( 'summary', summary );
|
|
186
214
|
wordCount = wordCount ?? 50;
|
|
187
215
|
|
|
188
216
|
// gemini-nano has a tendency to exceed the word count, so we need to check and summarize again if necessary
|
|
189
217
|
if ( summary.split( ' ' ).length > wordCount ) {
|
|
218
|
+
debug( 'summary exceeds word count' );
|
|
190
219
|
summary = await summarizer.summarize( summary, { context: context } );
|
|
191
220
|
}
|
|
192
221
|
|
|
@@ -199,6 +228,7 @@ export default class ChromeAISuggestionsEventSource extends EventTarget {
|
|
|
199
228
|
} ),
|
|
200
229
|
} );
|
|
201
230
|
} catch ( error ) {
|
|
231
|
+
debug( 'error', error );
|
|
202
232
|
this.processErrorEvent( error );
|
|
203
233
|
}
|
|
204
234
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { isWoASite, isSimpleSite } from '@automattic/jetpack-script-data';
|
|
5
5
|
import { useState } from '@wordpress/element';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -11,7 +11,7 @@ import { useState } from '@wordpress/element';
|
|
|
11
11
|
*/
|
|
12
12
|
export default function useSiteType() {
|
|
13
13
|
const getSiteType = () => {
|
|
14
|
-
if (
|
|
14
|
+
if ( isWoASite() ) {
|
|
15
15
|
return 'atomic';
|
|
16
16
|
}
|
|
17
17
|
if ( isSimpleSite() ) {
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
4
|
import getRedirectUrl from '@automattic/jetpack-components/tools/jp-redirect';
|
|
5
|
+
import { isWpcomPlatformSite, isSimpleSite } from '@automattic/jetpack-script-data';
|
|
5
6
|
import {
|
|
6
|
-
isAtomicSite,
|
|
7
|
-
isSimpleSite,
|
|
8
7
|
getSiteFragment,
|
|
9
8
|
useAutosaveAndRedirect,
|
|
10
9
|
} from '@automattic/jetpack-shared-extension-utils';
|
|
@@ -53,7 +52,7 @@ export default function useAICheckout(): UseAICheckoutReturn {
|
|
|
53
52
|
path: 'jetpack_ai_yearly',
|
|
54
53
|
} );
|
|
55
54
|
|
|
56
|
-
const checkoutUrl =
|
|
55
|
+
const checkoutUrl = isWpcomPlatformSite() ? wpcomCheckoutUrl : jetpackCheckoutUrl;
|
|
57
56
|
|
|
58
57
|
const { autosaveAndRedirect, isRedirecting } = useAutosaveAndRedirect( checkoutUrl );
|
|
59
58
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { useCallback, useEffect, useRef, useState } from '@wordpress/element';
|
|
5
5
|
import { __ } from '@wordpress/i18n';
|
|
6
|
+
import debugFactory from 'debug';
|
|
6
7
|
/**
|
|
7
8
|
* Internal dependencies
|
|
8
9
|
*/
|
|
@@ -31,6 +32,8 @@ import type {
|
|
|
31
32
|
AiModelTypeProp,
|
|
32
33
|
} from '../../types.ts';
|
|
33
34
|
|
|
35
|
+
const debug = debugFactory( 'ai-client:use-ai-suggestions' );
|
|
36
|
+
|
|
34
37
|
export type RequestingErrorProps = {
|
|
35
38
|
/*
|
|
36
39
|
* A string code to refer to the error.
|
|
@@ -252,9 +255,11 @@ export default function useAiSuggestions( {
|
|
|
252
255
|
*/
|
|
253
256
|
const handleSuggestion = useCallback(
|
|
254
257
|
( event: CustomEvent ) => {
|
|
258
|
+
debug( 'handleSuggestion', event );
|
|
255
259
|
const partialSuggestion = removeLlamaArtifact( event?.detail );
|
|
256
260
|
|
|
257
261
|
if ( ! partialSuggestion ) {
|
|
262
|
+
debug( 'no partial suggestion' );
|
|
258
263
|
return;
|
|
259
264
|
}
|
|
260
265
|
|
|
@@ -335,6 +340,7 @@ export default function useAiSuggestions( {
|
|
|
335
340
|
|
|
336
341
|
// check if we can (or should) use Chrome AI
|
|
337
342
|
const chromeAI = await ChromeAIFactory( promptArg );
|
|
343
|
+
debug( 'chromeAI', chromeAI !== false );
|
|
338
344
|
|
|
339
345
|
if ( chromeAI !== false ) {
|
|
340
346
|
setModelAndRef( AI_MODEL_GEMINI_NANO );
|
|
@@ -345,6 +351,7 @@ export default function useAiSuggestions( {
|
|
|
345
351
|
}
|
|
346
352
|
|
|
347
353
|
if ( ! eventSourceRef?.current ) {
|
|
354
|
+
debug( 'no event source' );
|
|
348
355
|
return;
|
|
349
356
|
}
|
|
350
357
|
|
package/src/jwt/index.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
isSimpleSite,
|
|
7
|
-
getSiteFragment,
|
|
8
|
-
} from '@automattic/jetpack-shared-extension-utils';
|
|
4
|
+
import { isWpcomPlatformSite } from '@automattic/jetpack-script-data';
|
|
5
|
+
import { getSiteFragment } from '@automattic/jetpack-shared-extension-utils';
|
|
9
6
|
import { useSelect } from '@wordpress/data';
|
|
10
7
|
/**
|
|
11
8
|
* Internal dependencies
|
|
@@ -25,7 +22,7 @@ export const useCheckout = () => {
|
|
|
25
22
|
};
|
|
26
23
|
}, [] );
|
|
27
24
|
|
|
28
|
-
const isJetpackSite = !
|
|
25
|
+
const isJetpackSite = ! isWpcomPlatformSite();
|
|
29
26
|
const redirectSource = isJetpackSite
|
|
30
27
|
? 'jetpack-ai-upgrade-url-for-jetpack-sites'
|
|
31
28
|
: 'jetpack-ai-yearly-tier-upgrade-nudge';
|