@@ -32,6 +32,7 @@ import {
3232 UserCog ,
3333 ChevronRight ,
3434 Settings ,
35+ Wrench ,
3536 type LucideIcon ,
3637} from "lucide-react"
3738import { useState , useEffect , useCallback , useMemo } from "react"
@@ -94,7 +95,11 @@ const META_TYPE_HINTS: Record<string, { label: string; icon: LucideIcon }> = {
9495 profiles : { label : 'Profiles' , icon : Shield } ,
9596 sharingRules : { label : 'Sharing Rules' , icon : Shield } ,
9697 policies : { label : 'Policies' , icon : Shield } ,
98+ agent : { label : 'Agents' , icon : Bot } ,
9799 agents : { label : 'Agents' , icon : Bot } ,
100+ tool : { label : 'Tools' , icon : Wrench } ,
101+ tools : { label : 'Tools' , icon : Wrench } ,
102+ ragPipeline : { label : 'RAG Pipelines' , icon : BookOpen } ,
98103 ragPipelines : { label : 'RAG Pipelines' , icon : BookOpen } ,
99104 apis : { label : 'APIs' , icon : Globe } ,
100105 connectors : { label : 'Connectors' , icon : Link2 } ,
@@ -123,7 +128,7 @@ const PROTOCOL_GROUPS: ProtocolGroup[] = [
123128 { key : 'ui' , label : 'UI' , icon : AppWindow , types : [ 'app' , 'apps' , 'actions' , 'views' , 'pages' , 'dashboards' , 'reports' , 'themes' ] } ,
124129 { key : 'automation' , label : 'Automation' , icon : Workflow , types : [ 'flows' , 'workflows' , 'approvals' , 'webhooks' ] } ,
125130 { key : 'security' , label : 'Security' , icon : Shield , types : [ 'roles' , 'permissions' , 'profiles' , 'sharingRules' , 'policies' ] } ,
126- { key : 'ai' , label : 'AI' , icon : Bot , types : [ 'agents' , 'ragPipelines' ] } ,
131+ { key : 'ai' , label : 'AI' , icon : Bot , types : [ 'agent' , ' agents' , 'tool' , 'tools' , 'ragPipeline ', 'ragPipelines' ] } ,
127132 { key : 'api' , label : 'API' , icon : Globe , types : [ 'apis' , 'connectors' ] } ,
128133] ;
129134
@@ -211,12 +216,32 @@ export function AppSidebar({
211216 } else if ( Array . isArray ( typesResult ) ) {
212217 types = typesResult as any ;
213218 }
214- setMetaTypes ( types ) ;
219+
220+ // Normalize types: prefer singular form (agent, tool) over plural (agents, tools)
221+ // when both exist in PROTOCOL_GROUPS, since the singular REST endpoint merges
222+ // SchemaRegistry items with MetadataService runtime items.
223+ const groupSingulars = new Set ( PROTOCOL_GROUPS . flatMap ( g => g . types ) . filter ( t => ! t . endsWith ( 's' ) ) ) ;
224+ const normalized = types . map ( t => {
225+ if ( t . endsWith ( 's' ) && groupSingulars . has ( t . slice ( 0 , - 1 ) ) ) {
226+ return t . slice ( 0 , - 1 ) ; // agents → agent, tools → tool
227+ }
228+ return t ;
229+ } ) ;
230+ // Also add group types that aren't covered at all by the server types
231+ const groupTypes = PROTOCOL_GROUPS . flatMap ( g => g . types ) ;
232+ const coveredSet = new Set ( normalized ) ;
233+ const extraTypes = groupTypes . filter ( t => {
234+ if ( coveredSet . has ( t ) ) return false ;
235+ const variant = t . endsWith ( 's' ) ? t . slice ( 0 , - 1 ) : t + 's' ;
236+ return ! coveredSet . has ( variant ) ;
237+ } ) ;
238+ const allTypes = Array . from ( new Set ( [ ...normalized , ...extraTypes ] ) ) ;
239+ setMetaTypes ( allTypes ) ;
215240
216241 const packageId = selectedPackage ?. manifest ?. id ;
217242
218243 const entries = await Promise . all (
219- types
244+ allTypes
220245 . filter ( t => ! HIDDEN_TYPES . has ( t ) )
221246 . map ( async ( type ) => {
222247 try {
0 commit comments