@automattic/jetpack-ai-client 0.1.3 → 0.1.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.
- package/CHANGELOG.md +15 -0
- package/index.ts +1 -1
- package/package.json +2 -1
- package/src/components/ai-control/index.tsx +38 -28
- package/src/components/ai-control/style.scss +3 -0
- package/src/components/ai-status-indicator/style.scss +2 -0
- package/src/components/index.ts +2 -0
- package/src/data-flow/context.tsx +5 -0
- package/src/data-flow/with-ai-assistant-data.tsx +10 -1
- package/src/hooks/use-ai-suggestions/index.ts +50 -40
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,20 @@ 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.1.4] - 2023-08-14
|
|
9
|
+
### Added
|
|
10
|
+
- AI Client: Add border-box in AIControl. [#32419]
|
|
11
|
+
- AI Client: Export AiStatusIndicator. [#32397]
|
|
12
|
+
- AI Client: Import base styles in the AI status indicator component. [#32396]
|
|
13
|
+
- AI Control: Forward ref to consumer. [#32400]
|
|
14
|
+
- AI Control: Import jetpack-base-styles. [#32376]
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- AI Client: Expose stopSuggestion function on useAiSuggestions hook so the consumer can stop a suggestion in the middle. [#32382]
|
|
18
|
+
|
|
19
|
+
### Removed
|
|
20
|
+
- AI Client: Remove redundant switch case [#32405]
|
|
21
|
+
|
|
8
22
|
## [0.1.3] - 2023-08-09
|
|
9
23
|
### Added
|
|
10
24
|
- AI Client: Introduce disabled prop in AI Control. [#32326]
|
|
@@ -68,6 +82,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
68
82
|
- Updated package dependencies. [#31659]
|
|
69
83
|
- Updated package dependencies. [#31785]
|
|
70
84
|
|
|
85
|
+
[0.1.4]: https://github.com/Automattic/jetpack-ai-client/compare/v0.1.3...v0.1.4
|
|
71
86
|
[0.1.3]: https://github.com/Automattic/jetpack-ai-client/compare/v0.1.2...v0.1.3
|
|
72
87
|
[0.1.2]: https://github.com/Automattic/jetpack-ai-client/compare/v0.1.1...v0.1.2
|
|
73
88
|
[0.1.1]: https://github.com/Automattic/jetpack-ai-client/compare/v0.1.0...v0.1.1
|
package/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"private": false,
|
|
3
3
|
"name": "@automattic/jetpack-ai-client",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.4",
|
|
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": {
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
".": "./index.ts"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
+
"@automattic/jetpack-base-styles": "^0.6.5",
|
|
35
36
|
"@automattic/jetpack-connection": "workspace:*",
|
|
36
37
|
"@automattic/jetpack-shared-extension-utils": "^0.11.1",
|
|
37
38
|
"@microsoft/fetch-event-source": "2.0.1",
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
import { PlainText } from '@wordpress/block-editor';
|
|
5
5
|
import { Button } from '@wordpress/components';
|
|
6
6
|
import { useKeyboardShortcut } from '@wordpress/compose';
|
|
7
|
-
import { useRef } from '@wordpress/element';
|
|
7
|
+
import { forwardRef, useImperativeHandle, useRef } from '@wordpress/element';
|
|
8
8
|
import { __ } from '@wordpress/i18n';
|
|
9
9
|
import { Icon, closeSmall, check, arrowUp } from '@wordpress/icons';
|
|
10
10
|
import classNames from 'classnames';
|
|
11
|
+
import React from 'react';
|
|
11
12
|
/**
|
|
12
13
|
* Internal dependencies
|
|
13
14
|
*/
|
|
@@ -38,39 +39,46 @@ const noop = () => {};
|
|
|
38
39
|
* @param {Function} props.onSend - send request handler
|
|
39
40
|
* @param {Function} props.onStop - stop request handler
|
|
40
41
|
* @param {Function} props.onAccept - accept handler
|
|
42
|
+
* @param {object} ref - Auto injected ref from react
|
|
41
43
|
* @returns {object} - AI Control component
|
|
42
44
|
*/
|
|
43
|
-
export
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
45
|
+
export function AIControl(
|
|
46
|
+
{
|
|
47
|
+
disabled = false,
|
|
48
|
+
value = '',
|
|
49
|
+
placeholder = '',
|
|
50
|
+
showAccept = false,
|
|
51
|
+
acceptLabel = __( 'Accept', 'jetpack-ai-client' ),
|
|
52
|
+
showButtonsLabel = true,
|
|
53
|
+
isOpaque = false,
|
|
54
|
+
state = 'init',
|
|
55
|
+
onChange = noop,
|
|
56
|
+
onSend = noop,
|
|
57
|
+
onStop = noop,
|
|
58
|
+
onAccept = noop,
|
|
59
|
+
}: {
|
|
60
|
+
disabled?: boolean;
|
|
61
|
+
value: string;
|
|
62
|
+
placeholder?: string;
|
|
63
|
+
showAccept?: boolean;
|
|
64
|
+
acceptLabel?: string;
|
|
65
|
+
showButtonsLabel?: boolean;
|
|
66
|
+
isOpaque?: boolean;
|
|
67
|
+
state?: RequestingStateProp;
|
|
68
|
+
onChange?: ( newValue: string ) => void;
|
|
69
|
+
onSend?: ( currentValue: string ) => void;
|
|
70
|
+
onStop?: () => void;
|
|
71
|
+
onAccept?: () => void;
|
|
72
|
+
},
|
|
73
|
+
ref
|
|
74
|
+
) {
|
|
70
75
|
const promptUserInputRef = useRef( null );
|
|
71
76
|
const loading = state === 'requesting' || state === 'suggesting';
|
|
72
77
|
const showGuideLine = ! ( loading || disabled || value?.length || isOpaque );
|
|
73
78
|
|
|
79
|
+
// Pass the ref to forwardRef.
|
|
80
|
+
useImperativeHandle( ref, () => promptUserInputRef.current );
|
|
81
|
+
|
|
74
82
|
useKeyboardShortcut(
|
|
75
83
|
'mod+enter',
|
|
76
84
|
() => {
|
|
@@ -169,3 +177,5 @@ export default function AIControl( {
|
|
|
169
177
|
</div>
|
|
170
178
|
);
|
|
171
179
|
}
|
|
180
|
+
|
|
181
|
+
export default forwardRef( AIControl );
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@import '@automattic/jetpack-base-styles/root-variables';
|
|
2
|
+
|
|
1
3
|
// AI CONTROL
|
|
2
4
|
|
|
3
5
|
.jetpack-components-ai-control__container {
|
|
@@ -13,6 +15,7 @@
|
|
|
13
15
|
padding: 12px 14px;
|
|
14
16
|
gap: 8px;
|
|
15
17
|
align-items: center;
|
|
18
|
+
box-sizing: border-box;
|
|
16
19
|
|
|
17
20
|
&.is-opaque {
|
|
18
21
|
opacity: 0.4;
|
|
@@ -33,6 +33,11 @@ export type AiDataContextProps = {
|
|
|
33
33
|
*/
|
|
34
34
|
requestSuggestion: ( prompt: PromptProp, options?: AskQuestionOptionsArgProps ) => void;
|
|
35
35
|
|
|
36
|
+
/*
|
|
37
|
+
* Stop suggestion function
|
|
38
|
+
*/
|
|
39
|
+
stopSuggestion: () => void;
|
|
40
|
+
|
|
36
41
|
/*
|
|
37
42
|
* The Suggestions Event Source instance
|
|
38
43
|
*/
|
|
@@ -25,6 +25,7 @@ const withAiDataProvider = createHigherOrderComponent( ( WrappedComponent: React
|
|
|
25
25
|
error: requestingError,
|
|
26
26
|
requestingState,
|
|
27
27
|
request: requestSuggestion,
|
|
28
|
+
stopSuggestion,
|
|
28
29
|
eventSource,
|
|
29
30
|
} = useAiSuggestions();
|
|
30
31
|
|
|
@@ -37,8 +38,16 @@ const withAiDataProvider = createHigherOrderComponent( ( WrappedComponent: React
|
|
|
37
38
|
eventSource,
|
|
38
39
|
|
|
39
40
|
requestSuggestion,
|
|
41
|
+
stopSuggestion,
|
|
40
42
|
} ),
|
|
41
|
-
[
|
|
43
|
+
[
|
|
44
|
+
suggestion,
|
|
45
|
+
requestingError,
|
|
46
|
+
requestingState,
|
|
47
|
+
eventSource,
|
|
48
|
+
requestSuggestion,
|
|
49
|
+
stopSuggestion,
|
|
50
|
+
]
|
|
42
51
|
);
|
|
43
52
|
|
|
44
53
|
return (
|
|
@@ -97,6 +97,11 @@ type useAiSuggestionsProps = {
|
|
|
97
97
|
* The request handler.
|
|
98
98
|
*/
|
|
99
99
|
request: ( prompt: PromptProp, options?: AskQuestionOptionsArgProps ) => Promise< void >;
|
|
100
|
+
|
|
101
|
+
/*
|
|
102
|
+
* The handler to stop a suggestion.
|
|
103
|
+
*/
|
|
104
|
+
stopSuggestion: () => void;
|
|
100
105
|
};
|
|
101
106
|
|
|
102
107
|
const debug = debugFactory( 'jetpack-ai-client:use-suggestion' );
|
|
@@ -140,14 +145,6 @@ export function getErrorData( errorCode: SuggestionErrorCode ): RequestingErrorP
|
|
|
140
145
|
severity: 'info',
|
|
141
146
|
};
|
|
142
147
|
case ERROR_NETWORK:
|
|
143
|
-
return {
|
|
144
|
-
code: ERROR_NETWORK,
|
|
145
|
-
message: __(
|
|
146
|
-
'It was not possible to process your request. Mind trying again?',
|
|
147
|
-
'jetpack-ai-client'
|
|
148
|
-
),
|
|
149
|
-
severity: 'info',
|
|
150
|
-
};
|
|
151
148
|
default:
|
|
152
149
|
return {
|
|
153
150
|
code: ERROR_NETWORK,
|
|
@@ -297,6 +294,46 @@ export default function useAiSuggestions( {
|
|
|
297
294
|
]
|
|
298
295
|
);
|
|
299
296
|
|
|
297
|
+
/**
|
|
298
|
+
* Stop suggestion handler.
|
|
299
|
+
*
|
|
300
|
+
* @returns {void}
|
|
301
|
+
*/
|
|
302
|
+
const stopSuggestion = useCallback( () => {
|
|
303
|
+
if ( ! eventSourceRef?.current ) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Alias
|
|
308
|
+
const eventSource = eventSourceRef?.current;
|
|
309
|
+
|
|
310
|
+
// Close the connection.
|
|
311
|
+
eventSource.close();
|
|
312
|
+
|
|
313
|
+
// Clean up the event listeners.
|
|
314
|
+
eventSource.removeEventListener( 'suggestion', handleSuggestion );
|
|
315
|
+
|
|
316
|
+
eventSource.removeEventListener( ERROR_QUOTA_EXCEEDED, handleErrorQuotaExceededError );
|
|
317
|
+
eventSource.removeEventListener( ERROR_UNCLEAR_PROMPT, handleUnclearPromptError );
|
|
318
|
+
eventSource.removeEventListener( ERROR_SERVICE_UNAVAILABLE, handleServiceUnavailableError );
|
|
319
|
+
eventSource.removeEventListener( ERROR_MODERATION, handleModerationError );
|
|
320
|
+
eventSource.removeEventListener( ERROR_NETWORK, handleNetworkError );
|
|
321
|
+
|
|
322
|
+
eventSource.removeEventListener( 'done', handleDone );
|
|
323
|
+
|
|
324
|
+
// Set requesting state to done since the suggestion stopped.
|
|
325
|
+
setRequestingState( 'done' );
|
|
326
|
+
}, [
|
|
327
|
+
eventSourceRef,
|
|
328
|
+
handleSuggestion,
|
|
329
|
+
handleErrorQuotaExceededError,
|
|
330
|
+
handleUnclearPromptError,
|
|
331
|
+
handleServiceUnavailableError,
|
|
332
|
+
handleModerationError,
|
|
333
|
+
handleNetworkError,
|
|
334
|
+
handleDone,
|
|
335
|
+
] );
|
|
336
|
+
|
|
300
337
|
// Request suggestions automatically when ready.
|
|
301
338
|
useEffect( () => {
|
|
302
339
|
// Check if there is a prompt to request.
|
|
@@ -310,38 +347,10 @@ export default function useAiSuggestions( {
|
|
|
310
347
|
}
|
|
311
348
|
|
|
312
349
|
return () => {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// Alias
|
|
318
|
-
const eventSource = eventSourceRef.current;
|
|
319
|
-
|
|
320
|
-
// Close the connection.
|
|
321
|
-
eventSource.close();
|
|
322
|
-
|
|
323
|
-
// Clean up the event listeners.
|
|
324
|
-
eventSource.removeEventListener( 'suggestion', handleSuggestion );
|
|
325
|
-
|
|
326
|
-
eventSource.removeEventListener( ERROR_QUOTA_EXCEEDED, handleErrorQuotaExceededError );
|
|
327
|
-
eventSource.removeEventListener( ERROR_UNCLEAR_PROMPT, handleUnclearPromptError );
|
|
328
|
-
eventSource.removeEventListener( ERROR_SERVICE_UNAVAILABLE, handleServiceUnavailableError );
|
|
329
|
-
eventSource.removeEventListener( ERROR_MODERATION, handleModerationError );
|
|
330
|
-
eventSource.removeEventListener( ERROR_NETWORK, handleNetworkError );
|
|
331
|
-
|
|
332
|
-
eventSource.removeEventListener( 'done', handleDone );
|
|
350
|
+
// Stop the suggestion if the component unmounts.
|
|
351
|
+
stopSuggestion();
|
|
333
352
|
};
|
|
334
|
-
}, [
|
|
335
|
-
autoRequest,
|
|
336
|
-
handleDone,
|
|
337
|
-
handleErrorQuotaExceededError,
|
|
338
|
-
handleModerationError,
|
|
339
|
-
handleServiceUnavailableError,
|
|
340
|
-
handleSuggestion,
|
|
341
|
-
handleUnclearPromptError,
|
|
342
|
-
prompt,
|
|
343
|
-
request,
|
|
344
|
-
] );
|
|
353
|
+
}, [ autoRequest, prompt, request, stopSuggestion ] );
|
|
345
354
|
|
|
346
355
|
return {
|
|
347
356
|
// Data
|
|
@@ -349,8 +358,9 @@ export default function useAiSuggestions( {
|
|
|
349
358
|
error,
|
|
350
359
|
requestingState,
|
|
351
360
|
|
|
352
|
-
// Request
|
|
361
|
+
// Request/stop handlers
|
|
353
362
|
request,
|
|
363
|
+
stopSuggestion,
|
|
354
364
|
|
|
355
365
|
// SuggestionsEventSource
|
|
356
366
|
eventSource: eventSourceRef.current,
|