@automattic/jetpack-ai-client 0.6.0 → 0.7.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 +16 -0
- package/build/api-fetch/index.d.ts +7 -0
- package/build/api-fetch/index.js +6 -0
- package/build/ask-question/index.d.ts +2 -2
- package/build/ask-question/index.js +1 -1
- package/build/audio-transcription/index.d.ts +8 -0
- package/build/audio-transcription/index.js +49 -0
- package/build/components/ai-control/index.d.ts +1 -1
- package/build/components/ai-control/index.js +2 -2
- package/build/components/ai-status-indicator/index.d.ts +1 -1
- package/build/components/audio-duration-display/index.d.ts +3 -2
- package/build/components/audio-duration-display/index.js +3 -14
- package/build/components/audio-duration-display/lib/media.d.ts +13 -14
- package/build/components/audio-duration-display/lib/media.js +7 -32
- package/build/components/index.d.ts +4 -4
- package/build/components/index.js +4 -4
- package/build/data-flow/context.d.ts +5 -5
- package/build/data-flow/index.d.ts +3 -3
- package/build/data-flow/index.js +3 -3
- package/build/data-flow/use-ai-context.d.ts +3 -3
- package/build/data-flow/use-ai-context.js +2 -2
- package/build/data-flow/with-ai-assistant-data.js +2 -2
- package/build/hooks/use-ai-suggestions/index.d.ts +4 -4
- package/build/hooks/use-ai-suggestions/index.js +2 -2
- package/build/hooks/use-audio-transcription/index.d.ts +24 -0
- package/build/hooks/use-audio-transcription/index.js +49 -0
- package/build/hooks/use-media-recording/index.d.ts +30 -12
- package/build/hooks/use-media-recording/index.js +106 -40
- package/build/hooks/use-transcription-post-processing/index.d.ts +30 -0
- package/build/hooks/use-transcription-post-processing/index.js +84 -0
- package/build/icons/index.d.ts +7 -7
- package/build/icons/index.js +7 -7
- package/build/icons/mic.js +2 -2
- package/build/icons/player-pause.js +1 -1
- package/build/index.d.ts +12 -9
- package/build/index.js +12 -9
- package/build/jwt/index.js +4 -1
- package/build/suggestions-event-source/index.d.ts +1 -1
- package/build/suggestions-event-source/index.js +3 -3
- package/build/types.d.ts +5 -2
- package/build/types.js +4 -0
- package/package.json +12 -12
- package/src/api-fetch/index.ts +13 -0
- package/src/ask-question/index.ts +2 -2
- package/src/audio-transcription/index.ts +67 -0
- package/src/components/ai-control/index.tsx +3 -3
- package/src/components/ai-status-indicator/index.tsx +1 -1
- package/src/components/audio-duration-display/index.tsx +6 -17
- package/src/components/audio-duration-display/lib/media.ts +17 -40
- package/src/components/index.ts +4 -4
- package/src/data-flow/context.tsx +5 -5
- package/src/data-flow/index.ts +3 -3
- package/src/data-flow/use-ai-context.ts +4 -4
- package/src/data-flow/with-ai-assistant-data.tsx +2 -2
- package/src/hooks/use-ai-suggestions/index.ts +6 -6
- package/src/hooks/use-audio-transcription/index.ts +81 -0
- package/src/hooks/use-media-recording/Readme.md +2 -2
- package/src/hooks/use-media-recording/index.ts +161 -58
- package/src/hooks/use-transcription-post-processing/index.ts +135 -0
- package/src/icons/index.ts +7 -7
- package/src/icons/mic.tsx +14 -16
- package/src/icons/player-pause.tsx +5 -5
- package/src/index.ts +12 -9
- package/src/jwt/index.ts +4 -1
- package/src/suggestions-event-source/index.ts +4 -4
- package/src/types.ts +19 -2
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.7.0] - 2024-02-19
|
|
9
|
+
### Added
|
|
10
|
+
- AI Client: add support for audio transcriptions. [#35691]
|
|
11
|
+
- AI Client: add support for transcription post-processing. [#35734]
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- AI Client: Update voice to content feature [#35698]
|
|
15
|
+
- Make build usable in projects using tsc with `moduleResolution` set to 'nodenext'. [#35453]
|
|
16
|
+
- Voice to Content: Add states and refactor duration calculation [#35717]
|
|
17
|
+
|
|
18
|
+
## [0.6.1] - 2024-02-13
|
|
19
|
+
### Changed
|
|
20
|
+
- Updated package dependencies. [#35608]
|
|
21
|
+
|
|
8
22
|
## [0.6.0] - 2024-02-05
|
|
9
23
|
### Added
|
|
10
24
|
- Jetpack AI: Support floating error messaging on the AI Control component. [#35322]
|
|
@@ -206,6 +220,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
206
220
|
- Updated package dependencies. [#31659]
|
|
207
221
|
- Updated package dependencies. [#31785]
|
|
208
222
|
|
|
223
|
+
[0.7.0]: https://github.com/Automattic/jetpack-ai-client/compare/v0.6.1...v0.7.0
|
|
224
|
+
[0.6.1]: https://github.com/Automattic/jetpack-ai-client/compare/v0.6.0...v0.6.1
|
|
209
225
|
[0.6.0]: https://github.com/Automattic/jetpack-ai-client/compare/v0.5.1...v0.6.0
|
|
210
226
|
[0.5.1]: https://github.com/Automattic/jetpack-ai-client/compare/v0.5.0...v0.5.1
|
|
211
227
|
[0.5.0]: https://github.com/Automattic/jetpack-ai-client/compare/v0.4.1...v0.5.0
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import SuggestionsEventSource from '../suggestions-event-source';
|
|
2
|
-
import type { AiModelTypeProp, PromptProp } from '../types';
|
|
1
|
+
import SuggestionsEventSource from '../suggestions-event-source/index.js';
|
|
2
|
+
import type { AiModelTypeProp, PromptProp } from '../types.js';
|
|
3
3
|
export type AskQuestionOptionsArgProps = {
|
|
4
4
|
postId?: number;
|
|
5
5
|
fromCache?: boolean;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
4
|
import debugFactory from 'debug';
|
|
5
|
-
import SuggestionsEventSource from '../suggestions-event-source';
|
|
5
|
+
import SuggestionsEventSource from '../suggestions-event-source/index.js';
|
|
6
6
|
const debug = debugFactory('jetpack-ai-client:ask-question');
|
|
7
7
|
/**
|
|
8
8
|
* An asynchronous function that asks a question
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A function that takes an audio blob and transcribes it.
|
|
3
|
+
*
|
|
4
|
+
* @param {Blob} audio - The audio to be transcribed, from a recording or from a file.
|
|
5
|
+
* @param {string} feature - The feature name that is calling the transcription.
|
|
6
|
+
* @returns {Promise<string>} - The promise of a string containing the transcribed audio.
|
|
7
|
+
*/
|
|
8
|
+
export default function transcribeAudio(audio: Blob, feature?: string): Promise<string>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import debugFactory from 'debug';
|
|
5
|
+
/**
|
|
6
|
+
* Internal dependencies
|
|
7
|
+
*/
|
|
8
|
+
import apiFetch from '../api-fetch/index.js';
|
|
9
|
+
import requestJwt from '../jwt/index.js';
|
|
10
|
+
const debug = debugFactory('jetpack-ai-client:audio-transcription');
|
|
11
|
+
/**
|
|
12
|
+
* A function that takes an audio blob and transcribes it.
|
|
13
|
+
*
|
|
14
|
+
* @param {Blob} audio - The audio to be transcribed, from a recording or from a file.
|
|
15
|
+
* @param {string} feature - The feature name that is calling the transcription.
|
|
16
|
+
* @returns {Promise<string>} - The promise of a string containing the transcribed audio.
|
|
17
|
+
*/
|
|
18
|
+
export default async function transcribeAudio(audio, feature) {
|
|
19
|
+
debug('Transcribing audio: %o. Feature: %o', audio, feature);
|
|
20
|
+
// Get a token to use the transcription service
|
|
21
|
+
let token = '';
|
|
22
|
+
try {
|
|
23
|
+
token = (await requestJwt()).token;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
debug('Error getting token: %o', error);
|
|
27
|
+
return Promise.reject(error);
|
|
28
|
+
}
|
|
29
|
+
// Build a FormData object to hold the audio file
|
|
30
|
+
const formData = new FormData();
|
|
31
|
+
formData.append('audio_file', audio);
|
|
32
|
+
try {
|
|
33
|
+
const headers = {
|
|
34
|
+
Authorization: `Bearer ${token}`,
|
|
35
|
+
};
|
|
36
|
+
const response = await apiFetch({
|
|
37
|
+
url: `https://public-api.wordpress.com/wpcom/v2/jetpack-ai-transcription${feature ? `?feature=${feature}` : ''}`,
|
|
38
|
+
method: 'POST',
|
|
39
|
+
body: formData,
|
|
40
|
+
headers,
|
|
41
|
+
});
|
|
42
|
+
debug('Transcription response: %o', response);
|
|
43
|
+
return response.text;
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
debug('Transcription error response: %o', error);
|
|
47
|
+
return Promise.reject(error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -14,8 +14,8 @@ import React from 'react';
|
|
|
14
14
|
* Internal dependencies
|
|
15
15
|
*/
|
|
16
16
|
import './style.scss';
|
|
17
|
-
import AiStatusIndicator from '../ai-status-indicator';
|
|
18
|
-
import { GuidelineMessage } from './message';
|
|
17
|
+
import AiStatusIndicator from '../ai-status-indicator/index.js';
|
|
18
|
+
import { GuidelineMessage } from './message.js';
|
|
19
19
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
20
20
|
const noop = () => { };
|
|
21
21
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
type AudioDurationDisplayProps = {
|
|
3
|
-
|
|
3
|
+
duration: number;
|
|
4
|
+
className?: string | null;
|
|
4
5
|
};
|
|
5
6
|
/**
|
|
6
7
|
* AudioDurationDisplay component.
|
|
@@ -8,5 +9,5 @@ type AudioDurationDisplayProps = {
|
|
|
8
9
|
* @param {AudioDurationDisplayProps} props - Component props.
|
|
9
10
|
* @returns {React.ReactElement} Rendered component.
|
|
10
11
|
*/
|
|
11
|
-
export default function AudioDurationDisplay({
|
|
12
|
+
export default function AudioDurationDisplay({ duration, className, }: AudioDurationDisplayProps): React.ReactElement;
|
|
12
13
|
export {};
|
|
@@ -1,25 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
/*
|
|
3
|
-
* External dependencies
|
|
4
|
-
*/
|
|
5
|
-
import { useState, useEffect } from '@wordpress/element';
|
|
6
2
|
/*
|
|
7
3
|
* Internal dependencies
|
|
8
4
|
*/
|
|
9
|
-
import { formatTime
|
|
5
|
+
import { formatTime } from './lib/media.js';
|
|
10
6
|
/**
|
|
11
7
|
* AudioDurationDisplay component.
|
|
12
8
|
*
|
|
13
9
|
* @param {AudioDurationDisplayProps} props - Component props.
|
|
14
10
|
* @returns {React.ReactElement} Rendered component.
|
|
15
11
|
*/
|
|
16
|
-
export default function AudioDurationDisplay({
|
|
17
|
-
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
if (!url) {
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
getDuration(url).then(setDuration);
|
|
23
|
-
}, [url]);
|
|
24
|
-
return _jsx("span", { children: formatTime(duration, { addDecimalPart: false }) });
|
|
12
|
+
export default function AudioDurationDisplay({ duration, className, }) {
|
|
13
|
+
return _jsx("span", { className: className, children: formatTime(duration, { addDecimalPart: false }) });
|
|
25
14
|
}
|
|
@@ -1,29 +1,28 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Function to get duration of audio file
|
|
3
|
-
*
|
|
4
|
-
* @param {string} url - The url of the audio file
|
|
5
|
-
* @returns {Promise<number>} The duration of the audio file
|
|
6
|
-
* @see https://stackoverflow.com/questions/21522036/html-audio-tag-duration-always-infinity
|
|
7
|
-
*/
|
|
8
|
-
export declare function getDuration(url: string): Promise<number>;
|
|
9
1
|
type FormatTimeOptions = {
|
|
10
2
|
/**
|
|
11
3
|
* Whether to add the decimal part to the formatted time.
|
|
12
|
-
*
|
|
13
4
|
*/
|
|
14
5
|
addDecimalPart?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Whether to show the minutes part of the formatted time even when it's 0.
|
|
8
|
+
*/
|
|
9
|
+
showMinutes?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Whether to show the hours part of the formatted time even when it's 0.
|
|
12
|
+
*/
|
|
13
|
+
showHours?: boolean;
|
|
15
14
|
};
|
|
16
15
|
/**
|
|
17
16
|
* Formats the given time in milliseconds into a string with the format HH:MM:SS.DD,
|
|
18
17
|
* adding hours and minutes only when needed.
|
|
19
18
|
*
|
|
20
|
-
* @param {number} time - The time in
|
|
19
|
+
* @param {number} time - The time in milliseconds to format.
|
|
21
20
|
* @param {FormatTimeOptions} options - The arguments.
|
|
22
21
|
* @returns {string} The formatted time string.
|
|
23
22
|
* @example
|
|
24
|
-
* const formattedTime1 = formatTime( 1234567 );
|
|
25
|
-
* const formattedTime2 = formatTime( 45123 );
|
|
26
|
-
* const formattedTime3 = formatTime(
|
|
23
|
+
* const formattedTime1 = formatTime( 1234567, { addDecimalPart: true } ); // Returns "20:34.56"
|
|
24
|
+
* const formattedTime2 = formatTime( 45123 ); // Returns "00.45"
|
|
25
|
+
* const formattedTime3 = formatTime( 1200, { showHours: true } ); // Returns "00:00:01"
|
|
27
26
|
*/
|
|
28
|
-
export declare function formatTime(time: number, { addDecimalPart }?: FormatTimeOptions): string;
|
|
27
|
+
export declare function formatTime(time: number, { addDecimalPart, showMinutes, showHours }?: FormatTimeOptions): string;
|
|
29
28
|
export {};
|
|
@@ -1,48 +1,23 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Function to get duration of audio file
|
|
3
|
-
*
|
|
4
|
-
* @param {string} url - The url of the audio file
|
|
5
|
-
* @returns {Promise<number>} The duration of the audio file
|
|
6
|
-
* @see https://stackoverflow.com/questions/21522036/html-audio-tag-duration-always-infinity
|
|
7
|
-
*/
|
|
8
|
-
export function getDuration(url) {
|
|
9
|
-
return new Promise(next => {
|
|
10
|
-
const tmpAudioInstance = new Audio(url);
|
|
11
|
-
tmpAudioInstance.addEventListener('durationchange', function () {
|
|
12
|
-
if (this.duration === Infinity) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
const duration = this.duration;
|
|
16
|
-
tmpAudioInstance.remove(); // remove instance from memory
|
|
17
|
-
next(duration);
|
|
18
|
-
}, false);
|
|
19
|
-
tmpAudioInstance.load();
|
|
20
|
-
tmpAudioInstance.currentTime = 24 * 60 * 60; // Fake big time
|
|
21
|
-
tmpAudioInstance.volume = 0;
|
|
22
|
-
tmpAudioInstance.play(); // This will call `durationchange` event
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
1
|
/**
|
|
26
2
|
* Formats the given time in milliseconds into a string with the format HH:MM:SS.DD,
|
|
27
3
|
* adding hours and minutes only when needed.
|
|
28
4
|
*
|
|
29
|
-
* @param {number} time - The time in
|
|
5
|
+
* @param {number} time - The time in milliseconds to format.
|
|
30
6
|
* @param {FormatTimeOptions} options - The arguments.
|
|
31
7
|
* @returns {string} The formatted time string.
|
|
32
8
|
* @example
|
|
33
|
-
* const formattedTime1 = formatTime( 1234567 );
|
|
34
|
-
* const formattedTime2 = formatTime( 45123 );
|
|
35
|
-
* const formattedTime3 = formatTime(
|
|
9
|
+
* const formattedTime1 = formatTime( 1234567, { addDecimalPart: true } ); // Returns "20:34.56"
|
|
10
|
+
* const formattedTime2 = formatTime( 45123 ); // Returns "00.45"
|
|
11
|
+
* const formattedTime3 = formatTime( 1200, { showHours: true } ); // Returns "00:00:01"
|
|
36
12
|
*/
|
|
37
|
-
export function formatTime(time, { addDecimalPart = true } = {}) {
|
|
38
|
-
time = time * 1000;
|
|
13
|
+
export function formatTime(time, { addDecimalPart = false, showMinutes = true, showHours = false } = {}) {
|
|
39
14
|
const hours = Math.floor(time / 3600000);
|
|
40
15
|
const minutes = Math.floor(time / 60000) % 60;
|
|
41
16
|
const seconds = Math.floor(time / 1000) % 60;
|
|
42
17
|
const deciseconds = Math.floor(time / 10) % 100;
|
|
43
18
|
const parts = [
|
|
44
|
-
hours > 0 ? hours.toString().padStart(2, '0') + ':' : '',
|
|
45
|
-
hours > 0 || minutes > 0 ? minutes.toString().padStart(2, '0') + ':' : '',
|
|
19
|
+
hours > 0 || showHours ? hours.toString().padStart(2, '0') + ':' : '',
|
|
20
|
+
hours > 0 || minutes > 0 || showMinutes ? minutes.toString().padStart(2, '0') + ':' : '',
|
|
46
21
|
seconds.toString().padStart(2, '0'),
|
|
47
22
|
];
|
|
48
23
|
if (addDecimalPart) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { default as AIControl } from './ai-control';
|
|
2
|
-
export { default as AiStatusIndicator } from './ai-status-indicator';
|
|
3
|
-
export { default as AudioDurationDisplay } from './audio-duration-display';
|
|
4
|
-
export { GuidelineMessage, default as FooterMessage } from './ai-control/message';
|
|
1
|
+
export { default as AIControl } from './ai-control/index.js';
|
|
2
|
+
export { default as AiStatusIndicator } from './ai-status-indicator/index.js';
|
|
3
|
+
export { default as AudioDurationDisplay } from './audio-duration-display/index.js';
|
|
4
|
+
export { GuidelineMessage, default as FooterMessage } from './ai-control/message.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { default as AIControl } from './ai-control';
|
|
2
|
-
export { default as AiStatusIndicator } from './ai-status-indicator';
|
|
3
|
-
export { default as AudioDurationDisplay } from './audio-duration-display';
|
|
4
|
-
export { GuidelineMessage, default as FooterMessage } from './ai-control/message';
|
|
1
|
+
export { default as AIControl } from './ai-control/index.js';
|
|
2
|
+
export { default as AiStatusIndicator } from './ai-status-indicator/index.js';
|
|
3
|
+
export { default as AudioDurationDisplay } from './audio-duration-display/index.js';
|
|
4
|
+
export { GuidelineMessage, default as FooterMessage } from './ai-control/message.js';
|
|
@@ -2,11 +2,11 @@ import React from 'react';
|
|
|
2
2
|
/**
|
|
3
3
|
* Types & Constants
|
|
4
4
|
*/
|
|
5
|
-
import SuggestionsEventSource from '../suggestions-event-source';
|
|
6
|
-
import type { AskQuestionOptionsArgProps } from '../ask-question';
|
|
7
|
-
import type { RequestingErrorProps } from '../hooks/use-ai-suggestions';
|
|
8
|
-
import type { PromptProp } from '../types';
|
|
9
|
-
import type { RequestingStateProp } from '../types';
|
|
5
|
+
import SuggestionsEventSource from '../suggestions-event-source/index.js';
|
|
6
|
+
import type { AskQuestionOptionsArgProps } from '../ask-question/index.js';
|
|
7
|
+
import type { RequestingErrorProps } from '../hooks/use-ai-suggestions/index.js';
|
|
8
|
+
import type { PromptProp } from '../types.js';
|
|
9
|
+
import type { RequestingStateProp } from '../types.js';
|
|
10
10
|
export type AiDataContextProps = {
|
|
11
11
|
suggestion: string;
|
|
12
12
|
requestingError: RequestingErrorProps;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { AiDataContext, AiDataContextProvider } from './context';
|
|
2
|
-
export { default as withAiDataProvider } from './with-ai-assistant-data';
|
|
3
|
-
export { default as useAiContext } from './use-ai-context';
|
|
1
|
+
export { AiDataContext, AiDataContextProvider } from './context.js';
|
|
2
|
+
export { default as withAiDataProvider } from './with-ai-assistant-data.js';
|
|
3
|
+
export { default as useAiContext } from './use-ai-context.js';
|
package/build/data-flow/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { AiDataContext, AiDataContextProvider } from './context';
|
|
2
|
-
export { default as withAiDataProvider } from './with-ai-assistant-data';
|
|
3
|
-
export { default as useAiContext } from './use-ai-context';
|
|
1
|
+
export { AiDataContext, AiDataContextProvider } from './context.js';
|
|
2
|
+
export { default as withAiDataProvider } from './with-ai-assistant-data.js';
|
|
3
|
+
export { default as useAiContext } from './use-ai-context.js';
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Internal dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { RequestingErrorProps } from '../types';
|
|
4
|
+
import { RequestingErrorProps } from '../types.js';
|
|
5
5
|
/**
|
|
6
6
|
* Types & constants
|
|
7
7
|
*/
|
|
8
|
-
import type { AiDataContextProps } from './context';
|
|
9
|
-
import type { AskQuestionOptionsArgProps } from '../ask-question';
|
|
8
|
+
import type { AiDataContextProps } from './context.js';
|
|
9
|
+
import type { AskQuestionOptionsArgProps } from '../ask-question/index.js';
|
|
10
10
|
export type UseAiContextOptions = {
|
|
11
11
|
askQuestionOptions?: AskQuestionOptionsArgProps;
|
|
12
12
|
onDone?: (content: string) => void;
|
|
@@ -5,8 +5,8 @@ import { useCallback, useContext, useEffect } from '@wordpress/element';
|
|
|
5
5
|
/**
|
|
6
6
|
* Internal dependencies
|
|
7
7
|
*/
|
|
8
|
-
import { ERROR_RESPONSE } from '../types';
|
|
9
|
-
import { AiDataContext } from '.';
|
|
8
|
+
import { ERROR_RESPONSE } from '../types.js';
|
|
9
|
+
import { AiDataContext } from './index.js';
|
|
10
10
|
/**
|
|
11
11
|
* useAiContext hook to provide access to
|
|
12
12
|
* the AI Assistant data (from context),
|
|
@@ -7,8 +7,8 @@ import { useMemo } from '@wordpress/element';
|
|
|
7
7
|
/**
|
|
8
8
|
* Internal Dependencies
|
|
9
9
|
*/
|
|
10
|
-
import useAiSuggestions from '../hooks/use-ai-suggestions';
|
|
11
|
-
import { AiDataContextProvider } from '.';
|
|
10
|
+
import useAiSuggestions from '../hooks/use-ai-suggestions/index.js';
|
|
11
|
+
import { AiDataContextProvider } from './index.js';
|
|
12
12
|
/**
|
|
13
13
|
* High Order Component that provides the
|
|
14
14
|
* AI Assistant Data context to the wrapped component.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Types & constants
|
|
3
3
|
*/
|
|
4
|
-
import type { AskQuestionOptionsArgProps } from '../../ask-question';
|
|
5
|
-
import type SuggestionsEventSource from '../../suggestions-event-source';
|
|
6
|
-
import type { PromptProp, SuggestionErrorCode } from '../../types';
|
|
7
|
-
import type { RequestingStateProp } from '../../types';
|
|
4
|
+
import type { AskQuestionOptionsArgProps } from '../../ask-question/index.js';
|
|
5
|
+
import type SuggestionsEventSource from '../../suggestions-event-source/index.js';
|
|
6
|
+
import type { PromptProp, SuggestionErrorCode } from '../../types.js';
|
|
7
|
+
import type { RequestingStateProp } from '../../types.js';
|
|
8
8
|
export type RequestingErrorProps = {
|
|
9
9
|
code: SuggestionErrorCode;
|
|
10
10
|
message: string;
|
|
@@ -7,8 +7,8 @@ import debugFactory from 'debug';
|
|
|
7
7
|
/**
|
|
8
8
|
* Internal dependencies
|
|
9
9
|
*/
|
|
10
|
-
import askQuestion from '../../ask-question';
|
|
11
|
-
import { ERROR_MODERATION, ERROR_NETWORK, ERROR_QUOTA_EXCEEDED, ERROR_SERVICE_UNAVAILABLE, ERROR_UNCLEAR_PROMPT, } from '../../types';
|
|
10
|
+
import askQuestion from '../../ask-question/index.js';
|
|
11
|
+
import { ERROR_MODERATION, ERROR_NETWORK, ERROR_QUOTA_EXCEEDED, ERROR_SERVICE_UNAVAILABLE, ERROR_UNCLEAR_PROMPT, } from '../../types.js';
|
|
12
12
|
const debug = debugFactory('jetpack-ai-client:use-suggestion');
|
|
13
13
|
/**
|
|
14
14
|
* Get the error data for a given error code.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The response from the audio transcription hook.
|
|
3
|
+
*/
|
|
4
|
+
export type UseAudioTranscriptionReturn = {
|
|
5
|
+
transcriptionResult: string;
|
|
6
|
+
isTranscribingAudio: boolean;
|
|
7
|
+
transcriptionError: string;
|
|
8
|
+
transcribeAudio: (audio: Blob) => void;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* The props for the audio transcription hook.
|
|
12
|
+
*/
|
|
13
|
+
export type UseAudioTranscriptionProps = {
|
|
14
|
+
feature: string;
|
|
15
|
+
onReady?: (transcription: string) => void;
|
|
16
|
+
onError?: (error: string) => void;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* A hook to handle audio transcription.
|
|
20
|
+
*
|
|
21
|
+
* @param {string} feature - The feature name that is calling the transcription.
|
|
22
|
+
* @returns {UseAudioTranscriptionReturn} - Object with properties to get the transcription data.
|
|
23
|
+
*/
|
|
24
|
+
export default function useAudioTranscription({ feature, onReady, onError, }: UseAudioTranscriptionProps): UseAudioTranscriptionReturn;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useCallback, useState } from '@wordpress/element';
|
|
5
|
+
import debugFactory from 'debug';
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import transcribeAudio from '../../audio-transcription/index.js';
|
|
10
|
+
const debug = debugFactory('jetpack-ai-client:use-audio-transcription');
|
|
11
|
+
/**
|
|
12
|
+
* A hook to handle audio transcription.
|
|
13
|
+
*
|
|
14
|
+
* @param {string} feature - The feature name that is calling the transcription.
|
|
15
|
+
* @returns {UseAudioTranscriptionReturn} - Object with properties to get the transcription data.
|
|
16
|
+
*/
|
|
17
|
+
export default function useAudioTranscription({ feature, onReady, onError, }) {
|
|
18
|
+
const [transcriptionResult, setTranscriptionResult] = useState('');
|
|
19
|
+
const [transcriptionError, setTranscriptionError] = useState('');
|
|
20
|
+
const [isTranscribingAudio, setIsTranscribingAudio] = useState(false);
|
|
21
|
+
const handleAudioTranscription = useCallback((audio) => {
|
|
22
|
+
debug('Transcribing audio');
|
|
23
|
+
/**
|
|
24
|
+
* Reset the transcription result and error.
|
|
25
|
+
*/
|
|
26
|
+
setTranscriptionResult('');
|
|
27
|
+
setTranscriptionError('');
|
|
28
|
+
setIsTranscribingAudio(true);
|
|
29
|
+
/**
|
|
30
|
+
* Call the audio transcription library.
|
|
31
|
+
*/
|
|
32
|
+
transcribeAudio(audio, feature)
|
|
33
|
+
.then(transcriptionText => {
|
|
34
|
+
setTranscriptionResult(transcriptionText);
|
|
35
|
+
onReady?.(transcriptionText);
|
|
36
|
+
})
|
|
37
|
+
.catch(error => {
|
|
38
|
+
setTranscriptionError(error.message);
|
|
39
|
+
onError?.(error.message);
|
|
40
|
+
})
|
|
41
|
+
.finally(() => setIsTranscribingAudio(false));
|
|
42
|
+
}, [transcribeAudio, setTranscriptionResult, setTranscriptionError, setIsTranscribingAudio]);
|
|
43
|
+
return {
|
|
44
|
+
transcriptionResult,
|
|
45
|
+
isTranscribingAudio,
|
|
46
|
+
transcriptionError,
|
|
47
|
+
transcribeAudio: handleAudioTranscription,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
type RecordingStateProp = 'inactive' | 'recording' | 'paused';
|
|
1
|
+
type RecordingStateProp = 'inactive' | 'recording' | 'paused' | 'processing' | 'error';
|
|
2
2
|
type UseMediaRecordingProps = {
|
|
3
|
-
onDone?: (blob: Blob) => void;
|
|
3
|
+
onDone?: (blob: Blob, url: string) => void;
|
|
4
4
|
};
|
|
5
5
|
type UseMediaRecordingReturn = {
|
|
6
6
|
/**
|
|
@@ -16,21 +16,39 @@ type UseMediaRecordingReturn = {
|
|
|
16
16
|
*/
|
|
17
17
|
url: string | null;
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* The error message
|
|
20
20
|
*/
|
|
21
|
-
|
|
21
|
+
error: string | null;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* The duration of the recorded audio
|
|
24
24
|
*/
|
|
25
|
-
|
|
25
|
+
duration: number;
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
27
|
+
* The error handler
|
|
28
28
|
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
onError: (err: string | Error) => void;
|
|
30
|
+
controls: {
|
|
31
|
+
/**
|
|
32
|
+
* `start` recording handler
|
|
33
|
+
*/
|
|
34
|
+
start: (timeslice?: number) => void;
|
|
35
|
+
/**
|
|
36
|
+
* `pause` recording handler
|
|
37
|
+
*/
|
|
38
|
+
pause: () => void;
|
|
39
|
+
/**
|
|
40
|
+
* `resume` recording handler
|
|
41
|
+
*/
|
|
42
|
+
resume: () => void;
|
|
43
|
+
/**
|
|
44
|
+
* `stop` recording handler
|
|
45
|
+
*/
|
|
46
|
+
stop: () => void;
|
|
47
|
+
/**
|
|
48
|
+
* `reset` recording handler
|
|
49
|
+
*/
|
|
50
|
+
reset: () => void;
|
|
51
|
+
};
|
|
34
52
|
};
|
|
35
53
|
/**
|
|
36
54
|
* react custom hook to handle media recording.
|