Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
49 changes: 35 additions & 14 deletions packages/agents-manager/src/components/agent-dock/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import {
} from '@automattic/agenttic-ui';
import { useManagedOdieChat } from '@automattic/odie-client';
import { useDispatch, useSelect } from '@wordpress/data';
import { useState, useMemo } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { comment, drawerRight, login } from '@wordpress/icons';
import { Routes, Route, Navigate, useLocation, useNavigate } from 'react-router-dom';
import { LOCAL_TOOL_RUNNING_MESSAGE } from '../../constants';
import useAdminBarIntegration from '../../hooks/use-admin-bar-integration';
import useAgentLayoutManager from '../../hooks/use-agent-layout-manager';
import useConversation from '../../hooks/use-conversation';
Expand Down Expand Up @@ -46,7 +48,7 @@ interface AgentDockProps {
markdownExtensions?: MarkdownExtensions;
/** Navigation continuation hook for post-navigation conversation resumption. */
useNavigationContinuation?: NavigationContinuationHook;
/** Setup hook to register hook-dependent abilities. */
/** Hook for setting up abilities that utilize React context. Invoked after custom actions registration. */
useAbilitiesSetup?: AbilitiesSetupHook;
}

Expand All @@ -61,6 +63,8 @@ export default function AgentDock( {
useNavigationContinuation,
useAbilitiesSetup,
}: AgentDockProps ) {
const [ isThinking, setIsThinking ] = useState( false );
const [ deletedMessageIds, setDeletedMessageIds ] = useState< Set< string > >( new Set() );
const { setIsOpen, setIsDocked } = useDispatch( AGENTS_MANAGER_STORE );
const {
hasLoaded: isStoreReady,
Expand All @@ -86,13 +90,15 @@ export default function AgentDock( {
} );

const {
addMessage,
messages,
suggestions,
isProcessing,
error,
loadMessages,
onSubmit,
abortCurrentRequest,
clearSuggestions,
} = useAgentChat( agentConfig );

const {
Expand Down Expand Up @@ -136,9 +142,20 @@ export default function AgentDock( {
navigate,
} );

// Call setup hook to register hook-dependent abilities
// The hook is stable after loadedProviders is set (AgentDock only renders after providers load)
useAbilitiesSetup?.();
// Invoke abilities setup hook to register hook-based abilities that utilize React context.
// Provides custom action handlers for agent and chat interaction within Big Sky's AI store.
// The hook is stable as `AgentDock` only renders after external providers have been loaded.
useAbilitiesSetup?.( {
addMessage,
clearSuggestions,
getAgentManager,
setIsThinking,
deleteMarkedMessages: ( msgs ) => {
setDeletedMessageIds(
( prevIds ) => new Set( [ ...prevIds, ...msgs.map( ( msg ) => msg.id ) ] )
);
},
} );

const handleNewChat = () => {
navigate( '/' );
Expand All @@ -161,13 +178,6 @@ export default function AgentDock( {
icon: login,
title: __( 'Pop out sidebar', '__i18n_text_domain__' ),
onClick: () => {
// TODO: Persist floating chat position...
try {
window.localStorage?.setItem( 'agenttic-chat-position', 'right' );
} catch ( err ) {
// Ignore errors
}

undock();
setIsDocked( false );
},
Expand All @@ -192,11 +202,23 @@ export default function AgentDock( {
return options;
};

// Filter out deleted messages and local tool running messages
const visibleMessages = useMemo(
() =>
messages.filter(
( message ) =>
! deletedMessageIds.has( message.id ) &&
! message.content?.some( ( content ) => content?.text === LOCAL_TOOL_RUNNING_MESSAGE )
),
[ messages, deletedMessageIds ]
);

const Chat = (
<AgentChat
messages={ messages }
messages={ visibleMessages }
suggestions={ suggestions }
isProcessing={ isProcessing }
emptyViewSuggestions={ suggestions.length ? suggestions : emptyViewSuggestions }
isProcessing={ isProcessing || isThinking }
error={ error }
onSubmit={ onSubmit }
onAbort={ abortCurrentRequest }
Expand All @@ -208,7 +230,6 @@ export default function AgentDock( {
chatHeaderOptions={ getChatHeaderOptions() }
markdownComponents={ markdownComponents }
markdownExtensions={ markdownExtensions }
emptyViewSuggestions={ emptyViewSuggestions }
/>
);

Expand Down
2 changes: 2 additions & 0 deletions packages/agents-manager/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ export const API_BASE_URL = 'https://public-api.wordpress.com';

export const ORCHESTRATOR_AGENT_URL = `${ API_BASE_URL }/wpcom/v2/ai/agent`;
export const ORCHESTRATOR_AGENT_ID = 'wp-orchestrator';

export const LOCAL_TOOL_RUNNING_MESSAGE = 'local_tool_running';
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ $agents-manager-z-index-docked: 999999;
}

// Reposition the editor's template save confirmation panel
@mixin editor-save-panel-open( $save-panel-selector ) {
#{$save-panel-selector} {
@mixin editor-save-panel-open() {
.admin-ui-navigable-region.interface-interface-skeleton__actions {
margin: $layout-spacing 0;
right: $sidebar-width;
overflow: hidden;
Expand Down Expand Up @@ -258,9 +258,7 @@ body.next-admin.agents-manager-sidebar-container {

&.agents-manager-sidebar-container--sidebar-open {
@include sidebar-open-base( '.next-admin-layout__canvas.is-full-canvas' );
@include editor-save-panel-open(
'.admin-ui-navigable-region.interface-interface-skeleton__actions'
);
@include editor-save-panel-open();
}
}

Expand All @@ -275,9 +273,7 @@ body.site-editor-php.agents-manager-sidebar-container {

&.agents-manager-sidebar-container--sidebar-open {
@include sidebar-open-base( '.edit-site-layout__canvas' );
@include editor-save-panel-open(
'.interface-navigable-region.interface-interface-skeleton__actions'
);
@include editor-save-panel-open();

// Override canvas styles when the site editor navigation menu is open
.edit-site-layout:not( .is-full-canvas ) .edit-site-layout__canvas {
Expand All @@ -297,9 +293,7 @@ body.post-php.agents-manager-sidebar-container {

&.agents-manager-sidebar-container--sidebar-open {
@include sidebar-open-base( '.edit-post-layout' );
@include editor-save-panel-open(
'.interface-navigable-region.interface-interface-skeleton__actions'
);
@include editor-save-panel-open();
}
}

Expand Down Expand Up @@ -506,8 +500,6 @@ body.post-php.agents-manager-sidebar-container {
.edit-site-global-styles-variations_item-preview {
outline: 1px solid $gray-400;
outline-offset: 1px;
outline-color: #ccc;
outline-width: -wp-admin-border-width-focus;
}
}

Expand All @@ -518,7 +510,7 @@ body.post-php.agents-manager-sidebar-container {
}

.edit-site-global-styles-variations_item-preview {
outline-color: #545454;
outline: 1px solid #545454;
overflow: hidden;
}
}
Expand Down Expand Up @@ -696,4 +688,24 @@ body.post-php.agents-manager-sidebar-container {
.agents-manager-chat--undocked .agenttic.Chat-module_container.Chat-module_floating {
// Fix the undocked chat overlapping with the nav menu
z-index: 9999;

.big-sky__dock__menu__variation-picker .edit-site-global-styles-variations_item {
&.is-active,
&:focus-visible {
.edit-site-global-styles-variations_item-preview {
outline: 1px solid #0000001a;
}
}

&:not( .is-active ):hover {
.edit-site-global-styles-variations_item-preview {
outline-color: #00000080;
}
}

.edit-site-global-styles-variations_item-preview {
outline: 1px solid #0000004d;
overflow: hidden;
}
}
}
18 changes: 12 additions & 6 deletions packages/agents-manager/src/utils/load-external-providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
* PHP filter. Each provider module should export toolProvider and/or contextProvider.
*/

import { getAgentManager } from '@automattic/agenttic-client';
import type { ToolProvider, ContextProvider, Suggestion } from '../types';
import type { SubmitOptions } from '@automattic/agenttic-client';
import type { SubmitOptions, UseAgentChatReturn } from '@automattic/agenttic-client';
import type { MarkdownComponents, MarkdownExtensions } from '@automattic/agenttic-ui';

/**
* Check if the unified experience flag is set via agentsManagerData.
*
* This is used on wp-admin environments (Atomic, Garden, Simple sites) where
* the flag is injected server-side by Jetpack's Agents Manager.
*
* @returns The useUnifiedExperience value, or undefined if not available.
*/
export function getUseUnifiedExperienceFromInlineData(): boolean | undefined {
Expand All @@ -37,11 +37,17 @@ export type NavigationContinuationHook = ( props: {
} ) => void;

/**
* Abilities setup hook type - provided by environments that need to register
* hook-dependent abilities (abilities that require React context to work).
* Called from AgentDock component to provide React context.
* Abilities setup hook type - for registering hook-based abilities that utilize React
* context. Invoked after custom actions registration with Big Sky's AI store. Receives
* action handlers that will be used for agent and chat interaction.
*/
export type AbilitiesSetupHook = () => void;
export type AbilitiesSetupHook = ( actions: {
addMessage: UseAgentChatReturn[ 'addMessage' ];
clearSuggestions: UseAgentChatReturn[ 'clearSuggestions' ];
getAgentManager: typeof getAgentManager;
setIsThinking: ( isThinking: boolean ) => void;
deleteMarkedMessages: ( messages: Record< 'id', string >[] ) => void;
} ) => void;

export interface LoadedProviders {
toolProvider?: ToolProvider;
Expand Down