Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AI Assistant: Add Jetpack AI module and disable all features when the module is disabled #40532

Open
wants to merge 23 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
55c4e2a
add Jetpack AI module
dhasilva Dec 9, 2024
ec8d793
add useAiModule hook on Jetpack AI Client
dhasilva Dec 9, 2024
973073f
check AI module on runtime for extensions
dhasilva Dec 9, 2024
1b0e060
changelog
dhasilva Dec 9, 2024
7f207e8
remove end period from module description
dhasilva Dec 9, 2024
2084812
Merge remote-tracking branch 'origin/trunk' into add/jetpack-ai-modul…
dhasilva Dec 10, 2024
2f57993
remove unnecessary function
dhasilva Dec 10, 2024
4471d40
change module first introduced version
dhasilva Dec 10, 2024
d605f6e
move useBlockModuleStatus hook to AI Client js-package
dhasilva Dec 10, 2024
33fb563
check AI module on runtime for logo extension
dhasilva Dec 10, 2024
c099bb9
check AI module on runtime for image, featured image and logo blocks
dhasilva Dec 10, 2024
0f08466
Merge remote-tracking branch 'origin/trunk' into add/jetpack-ai-modul…
dhasilva Dec 11, 2024
b3028ef
check AI module on runtime for write brief highlights
dhasilva Dec 11, 2024
6889821
check AI module on runtime for the AI sidebar
dhasilva Dec 11, 2024
5ae6ee8
check AI module on runtime for the AI excerpt panel
dhasilva Dec 11, 2024
9133a3e
fix type
dhasilva Dec 11, 2024
4655205
Merge remote-tracking branch 'origin/trunk' into add/jetpack-ai-modul…
dhasilva Dec 11, 2024
537a736
add module checks on all AI registration processes. Module status hye…
CGastrell Dec 11, 2024
1cb27d7
Revert "check AI module on runtime for the AI excerpt panel"
dhasilva Dec 12, 2024
66a3893
Merge remote-tracking branch 'origin/trunk' into add/jetpack-ai-modul…
dhasilva Dec 12, 2024
39f9e15
remove ai excerpt if ai module is deactivated in the editor
dhasilva Dec 12, 2024
903b162
update changelog
dhasilva Dec 12, 2024
431cf17
Merge remote-tracking branch 'origin/trunk' into add/jetpack-ai-modul…
dhasilva Dec 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Significance: patch
Type: added
Comment: Just added a small convenience hook


25 changes: 25 additions & 0 deletions projects/js-packages/ai-client/src/hooks/use-ai-module/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* External dependencies
*/
import { useModuleStatus } from '@automattic/jetpack-shared-extension-utils';

/**
* A convenience hook to get and update the status of the AI module.
*
* @return {object} - The status of the AI module.
*/
export default function useAiModule(): {
isAiModuleActive: boolean;
isChangingStatus: boolean;
isLoadingModules: boolean;
changeStatus: ( active: boolean ) => void;
} {
const {
isModuleActive: isAiModuleActive,
isChangingStatus,
isLoadingModules,
changeStatus,
} = useModuleStatus( 'ai' );

return { isAiModuleActive, isChangingStatus, isLoadingModules, changeStatus };
}
2 changes: 2 additions & 0 deletions projects/js-packages/ai-client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export { default as useAudioTranscription } from './hooks/use-audio-transcriptio
export { default as useTranscriptionPostProcessing } from './hooks/use-transcription-post-processing/index.js';
export { default as useAudioValidation } from './hooks/use-audio-validation/index.js';
export { default as useImageGenerator } from './hooks/use-image-generator/index.js';
export { default as useAiModule } from './hooks/use-ai-module/index.js';
export { default as useBlockModuleStatus } from './hooks/use-block-module-status/index.js';
export * from './hooks/use-image-generator/constants.js';

/*
Expand Down
30 changes: 26 additions & 4 deletions projects/plugins/jetpack/_inc/client/writing/composing.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Chip, getRedirectUrl } from '@automattic/jetpack-components';
import { getRedirectUrl } from '@automattic/jetpack-components';
import { __, _x } from '@wordpress/i18n';
import React from 'react';
import { connect } from 'react-redux';
Expand Down Expand Up @@ -47,14 +47,16 @@ export class Composing extends React.Component {
foundMarkdown = this.props.isModuleFound( 'markdown' ),
foundShortcodes = this.props.isModuleFound( 'shortcodes' ),
foundBlocks = this.props.isModuleFound( 'blocks' ),
foundAi = this.props.isModuleFound( 'ai' ),
foundMyJetpack = this.props.isMyJetpackReachable;

if (
! foundCopyPost &&
! foundLatex &&
! foundMarkdown &&
! foundShortcodes &&
! foundBlocks
! foundBlocks &&
! foundAi
) {
return null;
}
Expand All @@ -64,6 +66,7 @@ export class Composing extends React.Component {
copyPost = this.props.module( 'copy-post' ),
shortcodes = this.props.module( 'shortcodes' ),
blocks = this.props.module( 'blocks' ),
ai = this.props.module( 'ai' ),
copyPostSettings = (
<SettingsGroup
module={ copyPost }
Expand Down Expand Up @@ -204,13 +207,31 @@ export class Composing extends React.Component {
</CompactCard>
</>
),
aiSettings = (
<SettingsGroup
module={ ai }
support={ {
text: __( 'Enable the AI Assistant to help you write and edit content.', 'jetpack' ),
link: ai.learn_more_button,
} }
>
<FormFieldset>
<ModuleToggle
slug="ai"
activated={ !! this.props.getOptionValue( 'ai' ) }
toggling={ this.props.isSavingAnyOption( [ 'ai' ] ) }
toggleModule={ this.props.toggleModuleNow }
>
<span className="jp-form-toggle-explanation">{ ai.description }</span>
</ModuleToggle>
</FormFieldset>
</SettingsGroup>
),
aiAssistantLink = (
<CompactCard className="jp-settings-card__configure-link">
<a href={ `${ this.props.siteAdminUrl }admin.php?page=my-jetpack#/jetpack-ai` }>
{ __( 'Learn more about all Jetpack AI features', 'jetpack' ) }
</a>
{ /* TODO: remove this Chip once it's not longer "new" */ }
<Chip type="new" text={ __( 'New', 'jetpack' ) } />
</CompactCard>
);

Expand All @@ -226,6 +247,7 @@ export class Composing extends React.Component {
{ foundLatex && latexSettings }
{ foundShortcodes && shortcodeSettings }
{ foundBlocks && blocksSettings }
{ foundAi && aiSettings }
{ foundMyJetpack &&
! this.props.getOptionValue( 'jetpack_blocks_disabled' ) &&
aiAssistantLink }
Expand Down
4 changes: 4 additions & 0 deletions projects/plugins/jetpack/changelog/add-jetpack-ai-module
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: enhancement

AI Assistant: Add Jetpack AI module and disable extensions when it is disabled
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace Automattic\Jetpack\Extensions\AIAssistant;

use Automattic\Jetpack\Blocks;
use Automattic\Jetpack\Modules;
use Automattic\Jetpack\Status;
use Automattic\Jetpack\Status\Host;
use Jetpack_Gutenberg;
Expand All @@ -23,7 +24,7 @@ function register_block() {
if (
( ( new Host() )->is_wpcom_simple()
|| ! ( new Status() )->is_offline_mode()
) && apply_filters( 'jetpack_ai_enabled', true )
) && is_ai_enabled()
) {
Blocks::jetpack_register_block(
__DIR__,
Expand All @@ -33,6 +34,15 @@ function register_block() {
}
add_action( 'init', __NAMESPACE__ . '\register_block' );

/**
* Checks both the filter (jetpack_ai_enabled) and the module status (ai)
*
* @return bool
*/
function is_ai_enabled() {
return apply_filters( 'jetpack_ai_enabled', true ) && ( new Modules() )->is_active( 'ai' );
}

/**
* Jetpack AI Assistant block registration/dependency declaration.
*
Expand Down Expand Up @@ -60,7 +70,7 @@ function load_assets( $attr, $content ) {
add_action(
'jetpack_register_gutenberg_extensions',
function () {
if ( apply_filters( 'jetpack_ai_enabled', true ) ) {
if ( is_ai_enabled() ) {
\Jetpack_Gutenberg::set_extension_available( 'ai-assistant-support' );
}
}
Expand All @@ -72,7 +82,7 @@ function () {
add_action(
'jetpack_register_gutenberg_extensions',
function () {
if ( apply_filters( 'jetpack_ai_enabled', true ) ) {
if ( is_ai_enabled() ) {
\Jetpack_Gutenberg::set_extension_available( 'ai-assistant-form-support' );
}
}
Expand All @@ -84,7 +94,7 @@ function () {
add_action(
'jetpack_register_gutenberg_extensions',
function () {
if ( apply_filters( 'jetpack_ai_enabled', true ) ) {
if ( is_ai_enabled() ) {
\Jetpack_Gutenberg::set_extension_available( 'ai-content-lens' );
}
}
Expand All @@ -96,7 +106,7 @@ function () {
add_action(
'jetpack_register_gutenberg_extensions',
function () {
if ( apply_filters( 'jetpack_ai_enabled', true ) ) {
if ( is_ai_enabled() ) {
\Jetpack_Gutenberg::set_extension_available( 'ai-assistant-backend-prompts' );
}
}
Expand All @@ -108,7 +118,7 @@ function () {
add_action(
'jetpack_register_gutenberg_extensions',
function () {
if ( apply_filters( 'jetpack_ai_enabled', true ) ) {
if ( is_ai_enabled() ) {
\Jetpack_Gutenberg::set_extension_available( 'ai-assistant-usage-panel' );
}
}
Expand All @@ -120,7 +130,7 @@ function () {
add_action(
'jetpack_register_gutenberg_extensions',
function () {
if ( apply_filters( 'jetpack_ai_enabled', true ) ) {
if ( is_ai_enabled() ) {
\Jetpack_Gutenberg::set_extension_available( 'ai-featured-image-generator' );
}
}
Expand All @@ -132,7 +142,7 @@ function () {
add_action(
'jetpack_register_gutenberg_extensions',
function () {
if ( apply_filters( 'jetpack_ai_enabled', true ) ) {
if ( is_ai_enabled() ) {
\Jetpack_Gutenberg::set_extension_available( 'ai-title-optimization' );
}
}
Expand All @@ -144,7 +154,7 @@ function () {
add_action(
'jetpack_register_gutenberg_extensions',
function () {
if ( apply_filters( 'jetpack_ai_enabled', true ) ) {
if ( is_ai_enabled() ) {
\Jetpack_Gutenberg::set_extension_available( 'ai-assistant-experimental-image-generation-support' );
}
}
Expand All @@ -156,7 +166,7 @@ function () {
add_action(
'jetpack_register_gutenberg_extensions',
function () {
if ( apply_filters( 'jetpack_ai_enabled', true ) ) {
if ( is_ai_enabled() ) {
\Jetpack_Gutenberg::set_extension_available( 'ai-general-purpose-image-generator' );
}
}
Expand All @@ -168,7 +178,7 @@ function () {
add_action(
'jetpack_register_gutenberg_extensions',
function () {
if ( apply_filters( 'jetpack_ai_enabled', true ) && apply_filters( 'breve_enabled', true ) ) {
if ( is_ai_enabled() && apply_filters( 'breve_enabled', true ) ) {
\Jetpack_Gutenberg::set_extension_available( 'ai-proofread-breve' );
}
}
Expand All @@ -180,7 +190,7 @@ function () {
add_action(
'jetpack_register_gutenberg_extensions',
function () {
if ( apply_filters( 'jetpack_ai_enabled', true ) ) {
if ( is_ai_enabled() ) {
\Jetpack_Gutenberg::set_extension_available( 'ai-assistant-site-logo-support' );
}
}
Expand All @@ -192,7 +202,7 @@ function () {
add_action(
'jetpack_register_gutenberg_extensions',
function () {
if ( apply_filters( 'jetpack_ai_enabled', true ) ) {
if ( is_ai_enabled() ) {
\Jetpack_Gutenberg::set_extension_available( 'ai-title-optimization-keywords-support' );
}
}
Expand All @@ -204,7 +214,7 @@ function () {
add_action(
'jetpack_register_gutenberg_extensions',
function () {
if ( apply_filters( 'jetpack_ai_enabled', true ) &&
if ( is_ai_enabled() &&
apply_filters( 'list_to_table_transform_enabled', false )
) {
\Jetpack_Gutenberg::set_extension_available( 'ai-list-to-table-transform' );
Expand All @@ -218,7 +228,7 @@ function () {
add_action(
'jetpack_register_gutenberg_extensions',
function () {
if ( apply_filters( 'jetpack_ai_enabled', true ) &&
if ( is_ai_enabled() &&
apply_filters( 'ai_response_feedback_enabled', false )
) {
\Jetpack_Gutenberg::set_extension_available( 'ai-response-feedback' );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
ERROR_NETWORK,
ERROR_QUOTA_EXCEEDED,
useAiSuggestions,
useAiModule,
useBlockModuleStatus,
} from '@automattic/jetpack-ai-client';
import { BlockControls, useBlockProps } from '@wordpress/block-editor';
import { createHigherOrderComponent } from '@wordpress/compose';
Expand All @@ -19,7 +21,6 @@ import React from 'react';
*/
import useAiFeature from '../hooks/use-ai-feature';
import useAutoScroll from '../hooks/use-auto-scroll';
import useBlockModuleStatus from '../hooks/use-block-module-status';
import { mapInternalPromptTypeToBackendPromptType } from '../lib/prompt/backend-prompt';
import AiAssistantInput from './components/ai-assistant-input';
import AiAssistantExtensionToolbarDropdown from './components/ai-assistant-toolbar-dropdown';
Expand Down Expand Up @@ -546,10 +547,11 @@ const blockEditWithAiComponents = createHigherOrderComponent( BlockEdit => {
}

return props => {
const { isAiModuleActive } = useAiModule();
const isRequiredModulePresent = useBlockModuleStatus( props.name );

// If the required module is not enabled, return the original block edit component early.
if ( ! isRequiredModulePresent ) {
if ( ! isAiModuleActive || ! isRequiredModulePresent ) {
return <BlockEdit { ...props } />;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* External dependencies
*/
import { GeneratorModal } from '@automattic/jetpack-ai-client';
import { GeneratorModal, useAiModule, useBlockModuleStatus } from '@automattic/jetpack-ai-client';
import { BlockControls } from '@wordpress/block-editor';
import { getBlockType } from '@wordpress/blocks';
import { createHigherOrderComponent } from '@wordpress/compose';
Expand Down Expand Up @@ -89,7 +89,7 @@ const useSiteDetails = () => {
* HOC to add the AI button on the Site Logo toolbar.
*/
const siteLogoEditWithAiComponents = createHigherOrderComponent( BlockEdit => {
return props => {
function ExtendedBlock( props ) {
const [ isLogoGeneratorModalVisible, setIsLogoGeneratorModalVisible ] = useState( false );
const { setLogo } = useSetLogo();
const shouldSyncIcon = props?.attributes?.shouldSyncIcon || false;
Expand Down Expand Up @@ -143,6 +143,18 @@ const siteLogoEditWithAiComponents = createHigherOrderComponent( BlockEdit => {
/>
</>
);
}

return props => {
const { isAiModuleActive } = useAiModule();
const isRequiredModulePresent = useBlockModuleStatus( props.name );

// If the required module is not enabled, return the original block edit component early.
if ( ! isAiModuleActive || ! isRequiredModulePresent ) {
return <BlockEdit { ...props } />;
}

return <ExtendedBlock { ...props } />;
};
}, 'SiteLogoEditWithAiComponents' );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace Automattic\Jetpack\Extensions\AiAssistantPlugin;

use Automattic\Jetpack\Connection\Manager as Connection_Manager;
use Automattic\Jetpack\Modules;
use Automattic\Jetpack\Status;
use Automattic\Jetpack\Status\Host;

Expand All @@ -28,14 +29,23 @@ function register_plugin() {
new Host() )->is_wpcom_simple()
|| ( ( new Connection_Manager( 'jetpack' ) )->has_connected_owner() && ! ( new Status() )->is_offline_mode()
)
&& apply_filters( 'jetpack_ai_enabled', true )
&& is_ai_plugin_enabled()
) {
// Register AI assistant plugin.
\Jetpack_Gutenberg::set_extension_available( FEATURE_NAME );
}
}
add_action( 'jetpack_register_gutenberg_extensions', __NAMESPACE__ . '\register_plugin' );

/**
* Checks both the filter (jetpack_ai_enabled) and the module status (ai)
*
* @return bool
*/
function is_ai_plugin_enabled() {
return apply_filters( 'jetpack_ai_enabled', true ) && ( new Modules() )->is_active( 'ai' );
}

// Populate the available extensions with ai-assistant-plugin.
add_filter(
'jetpack_set_available_extensions',
Expand Down
Loading
Loading