diff --git a/inc/config.php b/inc/config.php index a439490..2f17b3b 100644 --- a/inc/config.php +++ b/inc/config.php @@ -19,6 +19,10 @@ function frontend_agent_chat_get_config(): array { 'agent_slug' => '', 'description' => __( 'Your AI assistant.', 'frontend-agent-chat' ), 'enabled' => false, + 'labels' => array( + 'agent_switcher_title' => __( 'Agent', 'frontend-agent-chat' ), + 'agent_select_label' => __( 'Select chat agent', 'frontend-agent-chat' ), + ), 'loading_messages' => true, ); @@ -106,7 +110,7 @@ function frontend_agent_chat_get_active_agent_slug(): string { * Normalize an Agents API descriptor for frontend chat use. * * @param array $agent Raw agent descriptor. - * @return array|null Normalized descriptor or null. + * @return array{agent_slug:string,agent_name:string,agent_description:string,meta:array}|null Normalized descriptor or null. */ function frontend_agent_chat_normalize_agent( array $agent ): ?array { $slug = sanitize_title( (string) ( $agent['slug'] ?? $agent['agent_slug'] ?? '' ) ); diff --git a/inc/enqueue.php b/inc/enqueue.php index 8c95dfb..4d83151 100644 --- a/inc/enqueue.php +++ b/inc/enqueue.php @@ -35,7 +35,9 @@ function frontend_agent_chat_enqueue() { if ( ! empty( $config['agent_slug'] ) ) { $agent = frontend_agent_chat_resolve_agent( (string) $config['agent_slug'] ); } - $agent = $agent ?: $agents[0]; + if ( ! $agent ) { + $agent = $agents[0]; + } $build_dir = FRONTEND_AGENT_CHAT_PLUGIN_DIR . 'build/'; $build_url = FRONTEND_AGENT_CHAT_PLUGIN_URL . 'build/'; @@ -70,6 +72,7 @@ function frontend_agent_chat_enqueue() { 'agentsPath' => '/frontend-agent-chat/v1/agents', 'agentName' => (string) ( $agent['agent_name'] ?? $agent['label'] ?? $config['agent_slug'] ), 'agentDescription' => (string) ( $agent['agent_description'] ?? $agent['description'] ?? $config['description'] ), + 'labels' => is_array( $config['labels'] ?? null ) ? $config['labels'] : array(), ); if ( ! empty( $config['loading_messages'] ) ) { diff --git a/inc/rest.php b/inc/rest.php index 3dbdf10..815187a 100644 --- a/inc/rest.php +++ b/inc/rest.php @@ -252,9 +252,9 @@ function frontend_agent_chat_rest_send_message( WP_REST_Request $request ) { return new WP_Error( 'frontend_agent_chat_empty_message', __( 'Message cannot be empty.', 'frontend-agent-chat' ), array( 'status' => 400 ) ); } - $config = frontend_agent_chat_get_config(); - $agent_slug = frontend_agent_chat_rest_get_agent_slug( $request, (string) ( $config['agent_slug'] ?? '' ) ); - $session_id = sanitize_text_field( (string) $request->get_param( 'session_id' ) ); + $config = frontend_agent_chat_get_config(); + $agent_slug = frontend_agent_chat_rest_get_agent_slug( $request, (string) ( $config['agent_slug'] ?? '' ) ); + $session_id = sanitize_text_field( (string) $request->get_param( 'session_id' ) ); if ( '' === $agent_slug ) { return new WP_Error( 'frontend_agent_chat_missing_agent', __( 'Agent is required.', 'frontend-agent-chat' ), array( 'status' => 400 ) ); } @@ -303,7 +303,7 @@ function frontend_agent_chat_rest_send_message( WP_REST_Request $request ) { */ $chat_input = apply_filters( 'frontend_agent_chat_chat_input', $chat_input, $request, $agent_slug, $config ); - $result = frontend_agent_chat_execute_ability( 'agents/chat', is_array( $chat_input ) ? $chat_input : array() ); + $result = frontend_agent_chat_execute_ability( 'agents/chat', $chat_input ); if ( is_wp_error( $result ) ) { return $result; @@ -403,7 +403,7 @@ function frontend_agent_chat_rest_list_sessions( WP_REST_Request $request ) { return new WP_Error( 'frontend_agent_chat_missing_agent', __( 'Agent is required.', 'frontend-agent-chat' ), array( 'status' => 400 ) ); } - $result = frontend_agent_chat_execute_ability( + $result = frontend_agent_chat_execute_ability( 'agents/list-conversation-sessions', array( 'limit' => $limit, diff --git a/src/AgentChat.tsx b/src/AgentChat.tsx index c3c94b4..c875686 100644 --- a/src/AgentChat.tsx +++ b/src/AgentChat.tsx @@ -39,6 +39,10 @@ interface AgentChatProps { agentsPath: string; agentName: string; agentDescription: string; + labels?: { + agent_switcher_title?: string; + agent_select_label?: string; + }; loadingMessages?: boolean | { mode?: 'default' | 'extend' | 'override'; messages?: string[]; @@ -167,6 +171,7 @@ export default function AgentChat( { agentsPath, agentName, agentDescription, + labels, loadingMessages = true, }: AgentChatProps ) { const [ isOpen, setIsOpen ] = useState( false ); @@ -185,6 +190,8 @@ export default function AgentChat( { const activeAgentSlug = selectedAgent?.slug ?? ''; const activeAgentName = selectedAgent?.name ?? agentName; const activeAgentDescription = selectedAgent?.description ?? agentDescription; + const agentSwitcherTitle = labels?.agent_switcher_title ?? __( 'Agent', 'frontend-agent-chat' ); + const agentSelectLabel = labels?.agent_select_label ?? __( 'Select chat agent', 'frontend-agent-chat' ); const fabLabel = __( 'Brain Chat', 'frontend-agent-chat' ); const agentFetch = useMemo( () => createAgentFetch( activeAgentSlug ), [ activeAgentSlug ] ); const open = useCallback( () => setIsOpen( true ), [] ); @@ -285,18 +292,27 @@ export default function AgentChat( { 'div', { className: 'frontend-agent-chat__agent' }, agents.length > 1 ? createElement( - 'select', - { - className: 'frontend-agent-chat__agent-select', - value: activeAgentSlug, - onChange: switchAgent, - 'aria-label': __( 'Select chat agent', 'frontend-agent-chat' ), - }, - agents.map( ( agent ) => createElement( - 'option', - { key: agent.slug, value: agent.slug }, - agent.name - ) ) + 'label', + { className: 'frontend-agent-chat__agent-switcher' }, + createElement( + 'span', + { className: 'frontend-agent-chat__agent-label' }, + agentSwitcherTitle + ), + createElement( + 'select', + { + className: 'frontend-agent-chat__agent-select', + value: activeAgentSlug, + onChange: switchAgent, + 'aria-label': agentSelectLabel, + }, + agents.map( ( agent ) => createElement( + 'option', + { key: agent.slug, value: agent.slug }, + agent.name + ) ) + ) ) : createElement( 'span', { className: 'frontend-agent-chat__title' }, diff --git a/src/agent-chat.css b/src/agent-chat.css index 6183071..17fd6f0 100644 --- a/src/agent-chat.css +++ b/src/agent-chat.css @@ -137,6 +137,20 @@ flex: 1; } +.frontend-agent-chat__agent-switcher { + display: flex; + align-items: center; + gap: 8px; + min-width: 0; +} + +.frontend-agent-chat__agent-label { + flex-shrink: 0; + font-size: 12px; + font-weight: 700; + color: var(--frontend-agent-chat-text-muted, #64748b); +} + .frontend-agent-chat__title { display: block; overflow: hidden; @@ -149,7 +163,9 @@ } .frontend-agent-chat__agent-select { - width: 100%; + width: auto; + min-width: 0; + flex: 1; max-width: 260px; min-height: 36px; padding: 0 32px 0 12px; diff --git a/src/index.ts b/src/index.ts index 7dfa98a..e61bea7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -33,6 +33,10 @@ declare global { agentsPath: string; agentName: string; agentDescription: string; + labels?: { + agent_switcher_title?: string; + agent_select_label?: string; + }; loadingMessages?: boolean | { mode?: 'default' | 'extend' | 'override'; messages?: string[]; @@ -74,6 +78,7 @@ function init(): void { agentsPath: config.agentsPath, agentName: config.agentName, agentDescription: config.agentDescription, + labels: config.labels, loadingMessages: config.loadingMessages ?? true, } ) );