@automattic/jetpack-ai-client 0.1.2 → 0.1.3

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,15 +5,29 @@ 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.3] - 2023-08-09
9
+ ### Added
10
+ - AI Client: Introduce disabled prop in AI Control. [#32326]
11
+ - AI Control: Add guideline message. [#32358]
12
+
13
+ ### Changed
14
+ - AI Client: handle token fetching errors by dispatching an event from the SuggestionsEventSource class. [#32350]
15
+ - AI Client: tweak layout and styles to make AI Control mobile friendly. [#32362]
16
+ - AI Control: clean up props. [#32360]
17
+ - Updated package dependencies. [#32166]
18
+
19
+ ### Fixed
20
+ - AI Client: fix TS type definition issue [#32330]
21
+
8
22
  ## [0.1.2] - 2023-08-07
9
23
  ### Added
10
- - AI Assistant: add options parameter to request function on useAiSuggestions hook [#32198]
24
+ - AI Assistant: Add options parameter to request function on useAiSuggestions hook [#32198]
11
25
  - AI Client: add @wordpress/compose dependency [#32228]
12
- - AI Client: add clear button in AI Control component [#32274]
13
- - AI Client: add keyboard shortcut to AIControl [#32239]
26
+ - AI Client: Add clear button in AI Control component [#32274]
27
+ - AI Client: Add keyboard shortcut to AIControl [#32239]
14
28
  - AI Client: add onError() response support [#32223]
15
- - AI Client: export types [#32209]
16
- - AI Client: start supporting request options on requestSuggestion callback. [#32303]
29
+ - AI Client: Export types [#32209]
30
+ - AI Client: Start supporting request options on requestSuggestion callback. [#32303]
17
31
  - AI Control: introduce AiStatusIndicator component [#32258]
18
32
 
19
33
  ### Changed
@@ -54,5 +68,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
54
68
  - Updated package dependencies. [#31659]
55
69
  - Updated package dependencies. [#31785]
56
70
 
71
+ [0.1.3]: https://github.com/Automattic/jetpack-ai-client/compare/v0.1.2...v0.1.3
57
72
  [0.1.2]: https://github.com/Automattic/jetpack-ai-client/compare/v0.1.1...v0.1.2
58
73
  [0.1.1]: https://github.com/Automattic/jetpack-ai-client/compare/v0.1.0...v0.1.1
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.2",
4
+ "version": "0.1.3",
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": {
@@ -33,16 +33,16 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@automattic/jetpack-connection": "workspace:*",
36
- "@automattic/jetpack-shared-extension-utils": "^0.11.0",
36
+ "@automattic/jetpack-shared-extension-utils": "^0.11.1",
37
37
  "@microsoft/fetch-event-source": "2.0.1",
38
- "@wordpress/api-fetch": "6.34.0",
39
- "@wordpress/block-editor": "12.5.0",
40
- "@wordpress/components": "25.3.0",
41
- "@wordpress/compose": "6.14.0",
42
- "@wordpress/data": "9.7.0",
43
- "@wordpress/element": "5.14.0",
44
- "@wordpress/i18n": "4.37.0",
45
- "@wordpress/icons": "9.28.0",
38
+ "@wordpress/api-fetch": "6.35.0",
39
+ "@wordpress/block-editor": "12.6.0",
40
+ "@wordpress/components": "25.4.0",
41
+ "@wordpress/compose": "6.15.0",
42
+ "@wordpress/data": "9.8.0",
43
+ "@wordpress/element": "5.15.0",
44
+ "@wordpress/i18n": "4.38.0",
45
+ "@wordpress/icons": "9.29.0",
46
46
  "classnames": "2.3.2",
47
47
  "debug": "4.3.4",
48
48
  "react": "18.2.0",
@@ -2,7 +2,6 @@
2
2
  * External dependencies
3
3
  */
4
4
  import debugFactory from 'debug';
5
- import requestJwt from '../jwt';
6
5
  import SuggestionsEventSource from '../suggestions-event-source';
7
6
  /*
8
7
  * Types & constants
@@ -62,11 +61,8 @@ export default async function askQuestion(
62
61
  ): Promise< SuggestionsEventSource > {
63
62
  debug( 'Asking question: %o. options: %o', question, { postId, fromCache, feature, functions } );
64
63
 
65
- const { token } = await requestJwt();
66
-
67
64
  return new SuggestionsEventSource( {
68
65
  question,
69
- token,
70
66
  options: { postId, feature, fromCache, functions },
71
67
  } );
72
68
  }
@@ -2,14 +2,14 @@
2
2
 
3
3
  #### Properties
4
4
 
5
- - `loading` (**boolean**) (Optional): Determines the loading state. Default value is `false`.
5
+ - `disabled` (**boolean**) (Optional): Disables the ai control. Default value is `false`.
6
6
  - `value` (**string**): Current input value. Default value is `''`.
7
7
  - `placeholder` (**string**) (Optional): Placeholder text for the input field. Default value is `''`.
8
8
  - `showAccept` (**boolean**) (Optional): Determines if the accept button is shown. Default value is `false`.
9
9
  - `acceptLabel` (**string**) (Optional): Label text for the accept button. Default value is `'Accept'`.
10
10
  - `showButtonsLabel` (**boolean**) (Optional): Determines if button labels are shown. Default value is `true`.
11
11
  - `isOpaque` (**boolean**) (Optional): Controls the opacity of the component. Default value is `false`.
12
- - `requestingState` (**RequestingStateProp**) (Optional): Determines the state of the request. Default value is `'init'`.
12
+ - `state` (**RequestingStateProp**) (Optional): Determines the state of the component. Default value is `'init'`.
13
13
  - `onChange` (**Function**) (Optional): Handler for input change. Default action is no operation.
14
14
  - `onSend` (**Function**) (Optional): Handler to send a request. Default action is no operation.
15
15
  - `onStop` (**Function**) (Optional): Handler to stop a request. Default action is no operation.
@@ -13,6 +13,7 @@ import classNames from 'classnames';
13
13
  */
14
14
  import './style.scss';
15
15
  import AiStatusIndicator from '../ai-status-indicator';
16
+ import { GuidelineMessage } from './message';
16
17
  /**
17
18
  * Types
18
19
  */
@@ -25,48 +26,50 @@ const noop = () => {};
25
26
  * AI Control component.
26
27
  *
27
28
  * @param {object} props - component props
28
- * @param {boolean} props.loading - loading state
29
+ * @param {boolean} props.disabled - is disabled
29
30
  * @param {string} props.value - input value
30
31
  * @param {string} props.placeholder - input placeholder
31
32
  * @param {boolean} props.showAccept - show accept button
32
33
  * @param {string} props.acceptLabel - accept button label
33
34
  * @param {boolean} props.showButtonsLabel - show buttons label
34
35
  * @param {boolean} props.isOpaque - is opaque
36
+ * @param {string} props.state - requesting state
35
37
  * @param {Function} props.onChange - input change handler
36
38
  * @param {Function} props.onSend - send request handler
37
39
  * @param {Function} props.onStop - stop request handler
38
40
  * @param {Function} props.onAccept - accept handler
39
- * @param {string} props.requestingState - requesting state
40
41
  * @returns {object} - AI Control component
41
42
  */
42
43
  export default function AIControl( {
43
- loading = false,
44
+ disabled = false,
44
45
  value = '',
45
46
  placeholder = '',
46
47
  showAccept = false,
47
48
  acceptLabel = __( 'Accept', 'jetpack-ai-client' ),
48
49
  showButtonsLabel = true,
49
50
  isOpaque = false,
50
- requestingState = 'init',
51
+ state = 'init',
51
52
  onChange = noop,
52
53
  onSend = noop,
53
54
  onStop = noop,
54
55
  onAccept = noop,
55
56
  }: {
56
- loading?: boolean;
57
+ disabled?: boolean;
57
58
  value: string;
58
59
  placeholder?: string;
59
60
  showAccept?: boolean;
60
61
  acceptLabel?: string;
61
62
  showButtonsLabel?: boolean;
62
63
  isOpaque?: boolean;
63
- requestingState?: RequestingStateProp;
64
+ state?: RequestingStateProp;
64
65
  onChange?: ( newValue: string ) => void;
65
66
  onSend?: ( currentValue: string ) => void;
66
67
  onStop?: () => void;
67
68
  onAccept?: () => void;
68
69
  } ) {
69
70
  const promptUserInputRef = useRef( null );
71
+ const loading = state === 'requesting' || state === 'suggesting';
72
+ const showGuideLine = ! ( loading || disabled || value?.length || isOpaque );
70
73
 
71
74
  useKeyboardShortcut(
72
75
  'mod+enter',
@@ -91,6 +94,10 @@ export default function AIControl( {
91
94
  }
92
95
  );
93
96
 
97
+ const actionButtonClasses = classNames( 'jetpack-components-ai-control__controls-prompt_button', {
98
+ 'has-label': showButtonsLabel,
99
+ } );
100
+
94
101
  return (
95
102
  <div className="jetpack-components-ai-control__container">
96
103
  <div
@@ -98,7 +105,7 @@ export default function AIControl( {
98
105
  'is-opaque': isOpaque,
99
106
  } ) }
100
107
  >
101
- <AiStatusIndicator state={ requestingState } />
108
+ <AiStatusIndicator state={ state } />
102
109
 
103
110
  <div className="jetpack-components-ai-control__input-wrapper">
104
111
  <PlainText
@@ -106,60 +113,59 @@ export default function AIControl( {
106
113
  onChange={ onChange }
107
114
  placeholder={ placeholder }
108
115
  className="jetpack-components-ai-control__input"
109
- disabled={ loading }
116
+ disabled={ loading || disabled }
110
117
  ref={ promptUserInputRef }
111
118
  />
119
+ </div>
120
+
121
+ { value?.length > 0 && (
122
+ <Button
123
+ icon={ closeSmall }
124
+ className="jetpack-components-ai-control__clear"
125
+ onClick={ () => onChange( '' ) }
126
+ />
127
+ ) }
112
128
 
113
- { value?.length > 0 && (
114
- <Icon
115
- icon={ closeSmall }
116
- className="jetpack-components-ai-control__clear"
117
- onClick={ () => onChange( '' ) }
118
- />
129
+ <div className="jetpack-components-ai-control__controls-prompt_button_wrapper">
130
+ { ! loading ? (
131
+ <Button
132
+ className={ actionButtonClasses }
133
+ onClick={ () => onSend( value ) }
134
+ isSmall={ true }
135
+ disabled={ ! value?.length || disabled }
136
+ label={ __( 'Send request', 'jetpack-ai-client' ) }
137
+ >
138
+ <Icon icon={ arrowUp } />
139
+ { showButtonsLabel && __( 'Send', 'jetpack-ai-client' ) }
140
+ </Button>
141
+ ) : (
142
+ <Button
143
+ className={ actionButtonClasses }
144
+ onClick={ onStop }
145
+ isSmall={ true }
146
+ label={ __( 'Stop request', 'jetpack-ai-client' ) }
147
+ >
148
+ <Icon icon={ closeSmall } />
149
+ { showButtonsLabel && __( 'Stop', 'jetpack-ai-client' ) }
150
+ </Button>
119
151
  ) }
120
152
  </div>
121
153
 
122
- <div className="jetpack-components-ai-control__controls">
154
+ { showAccept && (
123
155
  <div className="jetpack-components-ai-control__controls-prompt_button_wrapper">
124
- { ! loading ? (
125
- <Button
126
- className="jetpack-components-ai-control__controls-prompt_button"
127
- onClick={ () => onSend( value ) }
128
- isSmall={ true }
129
- disabled={ ! value?.length }
130
- label={ __( 'Send request', 'jetpack-ai-client' ) }
131
- >
132
- <Icon icon={ arrowUp } />
133
- { showButtonsLabel && __( 'Send', 'jetpack-ai-client' ) }
134
- </Button>
135
- ) : (
136
- <Button
137
- className="jetpack-components-ai-control__controls-prompt_button"
138
- onClick={ onStop }
139
- isSmall={ true }
140
- label={ __( 'Stop request', 'jetpack-ai-client' ) }
141
- >
142
- <Icon icon={ closeSmall } />
143
- { showButtonsLabel && __( 'Stop', 'jetpack-ai-client' ) }
144
- </Button>
145
- ) }
156
+ <Button
157
+ className={ actionButtonClasses }
158
+ onClick={ onAccept }
159
+ isSmall={ true }
160
+ label={ acceptLabel }
161
+ >
162
+ <Icon icon={ check } />
163
+ { showButtonsLabel && acceptLabel }
164
+ </Button>
146
165
  </div>
147
-
148
- { showAccept && (
149
- <div className="jetpack-components-ai-control__controls-prompt_button_wrapper">
150
- <Button
151
- className="jetpack-components-ai-control__controls-prompt_button"
152
- onClick={ onAccept }
153
- isSmall={ true }
154
- label={ acceptLabel }
155
- >
156
- <Icon icon={ check } />
157
- { acceptLabel }
158
- </Button>
159
- </div>
160
- ) }
161
- </div>
166
+ ) }
162
167
  </div>
168
+ { showGuideLine && <GuidelineMessage /> }
163
169
  </div>
164
170
  );
165
171
  }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { ExternalLink } from '@wordpress/components';
5
+ import { createInterpolateElement } from '@wordpress/element';
6
+ import { __ } from '@wordpress/i18n';
7
+ import {
8
+ Icon,
9
+ warning,
10
+ info,
11
+ cancelCircleFilled as error,
12
+ check as success,
13
+ } from '@wordpress/icons';
14
+ /**
15
+ * Types
16
+ */
17
+ import type React from 'react';
18
+
19
+ import './style.scss';
20
+
21
+ export const MESSAGE_SEVERITY_WARNING = 'warning';
22
+ export const MESSAGE_SEVERITY_ERROR = 'error';
23
+ export const MESSAGE_SEVERITY_SUCCESS = 'success';
24
+ export const MESSAGE_SEVERITY_INFO = 'info';
25
+
26
+ const messageSeverityTypes = [
27
+ MESSAGE_SEVERITY_WARNING,
28
+ MESSAGE_SEVERITY_ERROR,
29
+ MESSAGE_SEVERITY_SUCCESS,
30
+ MESSAGE_SEVERITY_INFO,
31
+ ] as const;
32
+
33
+ export type MessageSeverityProp = ( typeof messageSeverityTypes )[ number ] | null;
34
+
35
+ export type MessageProps = {
36
+ icon?: React.ReactNode;
37
+ children: React.ReactNode;
38
+ severity: MessageSeverityProp;
39
+ };
40
+
41
+ const messageIconsMap = {
42
+ [ MESSAGE_SEVERITY_WARNING ]: warning,
43
+ [ MESSAGE_SEVERITY_ERROR ]: error,
44
+ [ MESSAGE_SEVERITY_SUCCESS ]: success,
45
+ [ MESSAGE_SEVERITY_INFO ]: info,
46
+ };
47
+
48
+ /**
49
+ * React component to render a block message.
50
+ *
51
+ * @param {MessageProps} props - Component props.
52
+ * @returns {React.ReactElement } Banner component.
53
+ */
54
+ export default function Message( {
55
+ severity = null,
56
+ icon = null,
57
+ children,
58
+ }: MessageProps ): React.ReactElement {
59
+ return (
60
+ <div className="jetpack-ai-assistant__message">
61
+ { ( severity || icon ) && <Icon icon={ messageIconsMap[ severity ] || icon } /> }
62
+ <div className="jetpack-ai-assistant__message-content">{ children }</div>
63
+ </div>
64
+ );
65
+ }
66
+
67
+ /**
68
+ * React component to render a guideline message.
69
+ *
70
+ * @returns {React.ReactElement } - Message component.
71
+ */
72
+ export function GuidelineMessage(): React.ReactElement {
73
+ return (
74
+ <Message severity={ MESSAGE_SEVERITY_INFO }>
75
+ { createInterpolateElement(
76
+ __(
77
+ 'AI-generated content could be inaccurate or biased. <link>Learn more</link>',
78
+ 'jetpack-ai-client'
79
+ ),
80
+ {
81
+ link: <ExternalLink href="https://automattic.com/ai-guidelines" />,
82
+ }
83
+ ) }
84
+ </Message>
85
+ );
86
+ }
@@ -1,3 +1,5 @@
1
+ // AI CONTROL
2
+
1
3
  .jetpack-components-ai-control__container {
2
4
  color: var( --jp-gray-80 );
3
5
  background-color: var( --jp-white );
@@ -23,26 +25,11 @@
23
25
  flex-grow: 1;
24
26
  width: 100%;
25
27
 
26
- .jetpack-components-ai-control__clear {
27
- position: absolute;
28
- right: 8px;
29
- top: calc( 50% - 12px );
30
- border-radius: 50%;
31
- background-color: black;
32
- opacity: 0.2;
33
- fill: white;
34
- cursor: pointer;
35
-
36
- &:hover {
37
- opacity: 0.4;
38
- }
39
- }
40
-
41
28
  textarea.jetpack-components-ai-control__input {
42
29
  width: 100%;
43
30
  min-height: 20px;
44
31
  border-radius: 2px;
45
- padding: 6px 38px 6px 8px;
32
+ padding: 6px 8px;
46
33
 
47
34
  resize: none !important;
48
35
  border: none;
@@ -72,6 +59,21 @@
72
59
  }
73
60
  }
74
61
 
62
+ .jetpack-components-ai-control__clear.components-button.has-icon {
63
+ width: 24px;
64
+ min-width: 24px;
65
+ height: 24px;
66
+ padding: 0;
67
+ border-radius: 50%;
68
+ background-color: black;
69
+ opacity: 0.2;
70
+ color: white;
71
+
72
+ &:hover {
73
+ opacity: 0.4;
74
+ }
75
+ }
76
+
75
77
  .jetpack-components-ai-controlton__icon {
76
78
  flex-shrink: 0;
77
79
  display: flex;
@@ -94,11 +96,6 @@
94
96
  }
95
97
  }
96
98
 
97
- .jetpack-components-ai-control__controls {
98
- display: flex;
99
- align-items: center;
100
- }
101
-
102
99
  .jetpack-components-ai-control__controls-prompt_button_wrapper {
103
100
  text-transform: uppercase;
104
101
  font-size: 11px;
@@ -108,16 +105,16 @@
108
105
  white-space: nowrap;
109
106
  display: flex;
110
107
  align-items: center;
108
+
109
+ .components-button.is-small:not(.has-label) {
110
+ padding: 0;
111
+ }
111
112
  }
112
113
 
113
114
  .jetpack-components-ai-control__controls-prompt_button {
114
115
  color: var( --jp-gray-80 );
115
116
  text-transform: uppercase;
116
117
 
117
- > SVG {
118
- margin-right: 4px;
119
- }
120
-
121
118
  &:hover,
122
119
  &:active {
123
120
  color: var( --wp-components-color-accent, var( --wp-admin-theme-color ) );
@@ -127,4 +124,30 @@
127
124
  opacity: 0.6;
128
125
  cursor: not-allowed;
129
126
  }
130
- }
127
+ }
128
+
129
+ // MESSAGE
130
+
131
+ .jetpack-ai-assistant__message {
132
+ display: flex;
133
+ line-height: 28px;
134
+ font-size: 12px;
135
+ align-self: center;
136
+ align-items: center;
137
+ background-color: var( --jp-white-off );
138
+ padding: 0 12px;
139
+
140
+ > svg {
141
+ fill: var( --jp-gray-40 );
142
+ }
143
+
144
+ .jetpack-ai-assistant__message-content {
145
+ flex-grow: 2;
146
+ margin: 0 8px;
147
+ color: var( --jp-gray-70 );
148
+
149
+ .components-external-link {
150
+ color: var( --jp-gray-50 );
151
+ }
152
+ }
153
+ }
@@ -5,7 +5,7 @@ import { useCallback, useContext, useEffect } from '@wordpress/element';
5
5
  /**
6
6
  * Internal dependencies
7
7
  */
8
- import { ERROR_RESPONSE } from '../types';
8
+ import { ERROR_RESPONSE, RequestingErrorProps } from '../types';
9
9
  import { AiDataContext } from '.';
10
10
  /**
11
11
  * Types & constants
@@ -32,7 +32,7 @@ export type UseAiContextOptions = {
32
32
  /*
33
33
  * onError callback.
34
34
  */
35
- onError?: ( error: Error ) => void;
35
+ onError?: ( error: RequestingErrorProps ) => void;
36
36
  };
37
37
 
38
38
  /**
@@ -234,7 +234,7 @@ export default function useAiSuggestions( {
234
234
 
235
235
  const handleModerationError = useCallback( () => handleError( ERROR_MODERATION ), [] );
236
236
 
237
- const handleNetwotkError = useCallback( () => handleError( ERROR_NETWORK ), [] );
237
+ const handleNetworkError = useCallback( () => handleError( ERROR_NETWORK ), [] );
238
238
 
239
239
  /**
240
240
  * Request handler.
@@ -278,7 +278,7 @@ export default function useAiSuggestions( {
278
278
  eventSource.addEventListener( ERROR_UNCLEAR_PROMPT, handleUnclearPromptError );
279
279
  eventSource.addEventListener( ERROR_SERVICE_UNAVAILABLE, handleServiceUnavailableError );
280
280
  eventSource.addEventListener( ERROR_MODERATION, handleModerationError );
281
- eventSource.addEventListener( ERROR_NETWORK, handleNetwotkError );
281
+ eventSource.addEventListener( ERROR_NETWORK, handleNetworkError );
282
282
 
283
283
  eventSource.addEventListener( 'done', handleDone );
284
284
  } catch ( e ) {
@@ -292,7 +292,7 @@ export default function useAiSuggestions( {
292
292
  handleUnclearPromptError,
293
293
  handleServiceUnavailableError,
294
294
  handleModerationError,
295
- handleNetwotkError,
295
+ handleNetworkError,
296
296
  handleSuggestion,
297
297
  ]
298
298
  );
@@ -327,7 +327,7 @@ export default function useAiSuggestions( {
327
327
  eventSource.removeEventListener( ERROR_UNCLEAR_PROMPT, handleUnclearPromptError );
328
328
  eventSource.removeEventListener( ERROR_SERVICE_UNAVAILABLE, handleServiceUnavailableError );
329
329
  eventSource.removeEventListener( ERROR_MODERATION, handleModerationError );
330
- eventSource.removeEventListener( ERROR_NETWORK, handleNetwotkError );
330
+ eventSource.removeEventListener( ERROR_NETWORK, handleNetworkError );
331
331
 
332
332
  eventSource.removeEventListener( 'done', handleDone );
333
333
  };
@@ -3,10 +3,14 @@
3
3
  */
4
4
  import { EventSourceMessage, fetchEventSource } from '@microsoft/fetch-event-source';
5
5
  import debugFactory from 'debug';
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { getErrorData } from '../hooks/use-ai-suggestions';
10
+ import requestJwt from '../jwt';
6
11
  /*
7
12
  * Types & constants
8
13
  */
9
- import { getErrorData } from '../hooks/use-ai-suggestions';
10
14
  import {
11
15
  ERROR_MODERATION,
12
16
  ERROR_NETWORK,
@@ -20,7 +24,7 @@ import type { PromptMessagesProp, PromptProp, SuggestionErrorCode } from '../typ
20
24
  type SuggestionsEventSourceConstructorArgs = {
21
25
  url?: string;
22
26
  question: PromptProp;
23
- token: string;
27
+ token?: string;
24
28
  options?: {
25
29
  postId?: number;
26
30
  feature?: 'ai-assistant-experimental' | string | undefined;
@@ -81,6 +85,18 @@ export default class SuggestionsEventSource extends EventTarget {
81
85
  token,
82
86
  options = {},
83
87
  }: SuggestionsEventSourceConstructorArgs ) {
88
+ // If the token is not provided, try to get one
89
+ if ( ! token ) {
90
+ try {
91
+ debug( 'Token was not provided, requesting one...' );
92
+ token = ( await requestJwt() ).token;
93
+ } catch ( err ) {
94
+ this.processErrorEvent( err );
95
+
96
+ return;
97
+ }
98
+ }
99
+
84
100
  const bodyData: {
85
101
  post_id?: number;
86
102
  messages?: PromptMessagesProp;