Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/trunk' into update/local-transla…
Browse files Browse the repository at this point in the history
…tions
  • Loading branch information
d-alleyne committed Mar 9, 2025
2 parents 9080b7b + b29be00 commit 289f078
Show file tree
Hide file tree
Showing 14 changed files with 107 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Significance: patch
Type: added
Comment: Added utility functions


18 changes: 13 additions & 5 deletions projects/js-packages/ai-client/src/hooks/use-post-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,24 @@ const usePostContent = () => {
};
}, [] );

const getSerializedPostContent = useCallback( () => {
const blocks = getBlocks();

if ( blocks.length === 0 ) {
return '';
}

return serialize( blocks );
}, [ getBlocks ] );

const getPostContent = useCallback(
( preprocess?: ( serialized: string ) => string ) => {
const blocks = getBlocks();
let serialized = getSerializedPostContent();

if ( blocks.length === 0 ) {
if ( ! serialized ) {
return '';
}

let serialized = serialize( blocks );

if ( preprocess && typeof preprocess === 'function' ) {
serialized = preprocess( serialized );
}
Expand All @@ -47,7 +55,7 @@ const usePostContent = () => {
[ getBlocks ]
);

return { getPostContent, isEditedPostEmpty };
return { getPostContent, isEditedPostEmpty, getSerializedPostContent };
};

export default usePostContent;
29 changes: 29 additions & 0 deletions projects/js-packages/ai-client/src/libs/get-all-blocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* External dependencies
*/
import { select } from '@wordpress/data';
/**
* Internal dependencies
*/
import type { Block } from '../types.js';

/**
* Recursively get all blocks from the post, including nested innerBlocks
* @return {Array} Array of all blocks in the post
*/
export const getAllBlocks = (): Array< Block > => {
const topLevelBlocks = select( 'core/block-editor' ).getBlocks();
const allBlocks: Array< Block > = [];

const processBlock = ( block: Block ) => {
allBlocks.push( block );

if ( block.innerBlocks?.length ) {
block.innerBlocks.forEach( processBlock );
}
};

topLevelBlocks.forEach( processBlock );

return allBlocks;
};
2 changes: 2 additions & 0 deletions projects/js-packages/ai-client/src/libs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ export { mapActionToHumanText } from './map-action-to-human-text.js';
export { openBlockSidebar } from './open-block-sidebar.js';

export { showAiAssistantSection } from './show-ai-assistant-section.js';

export { getAllBlocks } from './get-all-blocks.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: other

JSON API: activate REST for posts fetching endpoint.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: other

AI Assistant: Add image index information on caption generation request
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: other

Newsletter Widget: hint dashboard placement for widget to be 2nd column, near the top
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,12 @@ public static function wp_dashboard_setup() {
wp_add_dashboard_widget(
self::$widget_id,
$widget_title,
array( static::class, 'render' )
array( static::class, 'render' ),
// @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
null,
array(),
'side',
'high'
);
}
}
Expand Down
4 changes: 3 additions & 1 deletion projects/plugins/jetpack/class.json-api-endpoints.php
Original file line number Diff line number Diff line change
Expand Up @@ -2820,7 +2820,9 @@ final public function rest_permission_callback() {
return new WP_Error( 'site_not_connected' );
}

if ( ( $this->allow_jetpack_site_auth && Rest_Authentication::is_signed_with_blog_token() ) || ( get_current_user_id() && Rest_Authentication::is_signed_with_user_token() ) ) {
if ( ( ( $this->allow_jetpack_site_auth || $this->allow_fallback_to_jetpack_blog_token ) && Rest_Authentication::is_signed_with_blog_token() )
|| ( get_current_user_id() && Rest_Authentication::is_signed_with_user_token() )
) {
$custom_permission_result = $this->rest_permission_callback_custom();

// Successful custom permission check.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,16 @@ const blockEditWithAiComponents = createHigherOrderComponent( BlockEdit => {
startLoading( type );

try {
const context: { positions?: number[] } = {};

if ( type === TYPE_ALT_TEXT ) {
openBlockSidebar( props.clientId );
}

if ( type === TYPE_CAPTION ) {
context.positions = [ props.clientId ];
}

dequeueAsyncRequest();

const response = await askQuestionSync(
Expand All @@ -150,8 +156,7 @@ const blockEditWithAiComponents = createHigherOrderComponent( BlockEdit => {
context: {
type: type,
content: getPostContent( preprocessImageContent ),
// URL of the image for the AI to find where the image is in the post.
urls: [ props.attributes.url ],
...context,
images: [
{
// We convert the image to a base64 string to avoid inaccesible URLs for private images.
Expand All @@ -169,7 +174,11 @@ const blockEditWithAiComponents = createHigherOrderComponent( BlockEdit => {

increaseRequestsCount();

const parsedResponse: { texts?: string[]; captions?: string[] } = JSON.parse( response );
const parsedResponse: { texts?: string[]; captions?: string[] } = JSON.parse(
response
?.replace?.( /^```json\s*/, '' ) // Remove the markdown code block if it exists.
?.replace( /```$/, '' )
);

if ( type === TYPE_ALT_TEXT ) {
const alt = parsedResponse.texts?.[ 0 ];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
/**
* Preprocess the serialized post content to remove image URLs and alt text, adding a unique count to each image.
* This is used to ensure that the AI is not confused by the URLs in the post content.
* External dependencies
*/
import { getAllBlocks } from '@automattic/jetpack-ai-client';

/**
* Preprocess the serialized post content to remove image captions and alt text, changing the image urls to their clientId.
* This is used to ensure that the AI is not confused by URLs in the post content, while still being able to identify the image blocks.
* @param {string} content - The content to preprocess.
* @return {string} The preprocessed content.
*/
export const preprocessImageContent = ( content: string ): string => {
let imageCounter = 0;
const imageBlocks = getAllBlocks().filter( block => block.name === 'core/image' );
let currentImageIndex = 0;

// Remove figcaption elements
content = content.replace( /<figcaption[^>]*>.*?<\/figcaption>/g, '' );

// Replace image URLs with a unique count and remove alt text
content = content.replace( /<img[^>]*>/g, () => {
imageCounter++;
// Replace the urls of images within image blocks with their clientId
content = content.replace( /<!-- wp:image[^>]*>.*?<img[^>]*>.*?<!-- \/wp:image -->/gs, () => {
// The assumption here is that the image blocks are always in the same order as the images in the post's HTML content
const imageBlock = imageBlocks[ currentImageIndex ];
currentImageIndex++;

if ( ! imageBlock ) {
return '';
}

return `<img src="image-${ imageCounter }">`;
return `<img src="${ imageBlock.clientId }">`;
} );

return content;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
'path_labels' => array(
'$site' => '(int|string) Site ID or domain',
),
'rest_route' => '/posts',
'rest_min_jp_version' => '14.5-a.1',

'allow_fallback_to_jetpack_blog_token' => true,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
'path_labels' => array(
'$site' => '(int|string) Site ID or domain',
),
'rest_route' => '/posts',
'rest_min_jp_version' => '14.5-a.1',

'allow_fallback_to_jetpack_blog_token' => true,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
'path_labels' => array(
'$site' => '(int|string) Site ID or domain',
),
'rest_route' => '/posts',
'rest_min_jp_version' => '14.5-a.1',

'allow_fallback_to_jetpack_blog_token' => true,

Expand Down

0 comments on commit 289f078

Please sign in to comment.