@@ -3,7 +3,7 @@ import { ref, computed } from 'vue'
33import { useI18n } from ' vue-i18n'
44import { apiFetch } from ' @/shared/api'
55import { store , applyMcpList } from ' @/shared/store'
6- import { useToast , useConfirm , SButton , SCard , SPageToolbar , SPageContent , STable , SInfoTable , SInfoRow , SModal , SInput , type STableColumn } from ' sbot-ui'
6+ import { useToast , useConfirm , SButton , SCard , SPageToolbar , SPageContent , STable , SInfoTable , SInfoRow , SModal , SInput , STagFilter , type STableColumn } from ' sbot-ui'
77import AgentModal from ' ./modals/AgentModal.vue'
88import AgentMcpModal from ' ./modals/AgentMcpModal.vue'
99import AgentSkillsModal from ' ./modals/AgentSkillsModal.vue'
@@ -25,6 +25,25 @@ const sortedAgentRows = computed<AgentRow[]>(() => {
2525 .map (([id , a ]) => ({ id , ... (a as any ) }))
2626 .sort ((a , b ) => order (a .type ) - order (b .type ))
2727})
28+
29+ const allTags = computed <string []>(() => {
30+ const set = new Set <string >()
31+ for (const a of Object .values (agents .value )) {
32+ const tags = (a as any ).tags
33+ if (Array .isArray (tags )) for (const t of tags ) if (t ) set .add (t )
34+ }
35+ return Array .from (set ).sort ()
36+ })
37+
38+ const activeTagFilters = ref <string []>([])
39+ const filteredAgentRows = computed <AgentRow []>(() => {
40+ if (activeTagFilters .value .length === 0 ) return sortedAgentRows .value
41+ return sortedAgentRows .value .filter (row => {
42+ const rowTags: string [] = Array .isArray (row .tags ) ? row .tags : []
43+ // AND 过滤:所选标签都需命中
44+ return activeTagFilters .value .every (t => rowTags .includes (t ))
45+ })
46+ })
2847const modelName = (id : string ) => (store .settings .models ?.[id ] as any )?.name || id
2948
3049const columns = computed <STableColumn []>(() => [
@@ -321,11 +340,15 @@ async function saveMcpParams() {
321340 <SPageToolbar >
322341 <SButton type="outline" size="sm" @click =" refresh " >{{ t('common.refresh') }}</SButton >
323342 <SButton type="primary" size="sm" @click =" agentModal ?.open ()" >{{ t('agents.add') }}</SButton >
343+ <div v-if =" allTags.length" class =" agents-tag-filter" >
344+ <span class =" agents-tag-filter-label" >{{ t('agents.filter_by_tag') }}</span >
345+ <STagFilter v-model =" activeTagFilters " :options =" allTags " />
346+ </div >
324347 </SPageToolbar >
325348 <SPageContent >
326349 <STable
327350 :columns =" columns "
328- :rows =" sortedAgentRows "
351+ :rows =" filteredAgentRows "
329352 row-key="id"
330353 expandable
331354 v-model :expandedKeys =" expandedIds "
@@ -338,6 +361,12 @@ async function saveMcpParams() {
338361 <span v-if =" row.skills === '*'" class =" config-badge config-badge-info" >{{ t('agents.tab_skills') }} *</span >
339362 <span v-if =" row.mcp === '*'" class =" config-badge config-badge-info" >{{ t('agents.tab_tools') }} *</span >
340363 <span v-if =" row.autoApproveAllTools" class =" config-badge config-badge-warn" >{{ t('agents.auto_approve_all_tools') }}</span >
364+ <span
365+ v-for =" tag in (row.tags || [])"
366+ :key =" tag"
367+ class =" config-badge config-badge-tag"
368+ :class =" { 'config-badge-tag-active': activeTagFilters.includes(tag) }"
369+ >{{ tag }}</span >
341370 </template >
342371
343372 <template #type =" { row } " >
@@ -552,6 +581,20 @@ async function saveMcpParams() {
552581.config-badge-id { background : #e0f2fe ; color : #0369a1 ; }
553582.config-badge-info { background : #dbeafe ; color : #1d4ed8 ; }
554583.config-badge-warn { background : #fef3c7 ; color : #b45309 ; }
584+ .config-badge-tag { background : #f1f5f9 ; color : #475569 ; }
585+ .config-badge-tag-active { background : #1f2937 ; color : #f9fafb ; }
586+
587+ .agents-tag-filter {
588+ display : flex ;
589+ align-items : center ;
590+ gap : var (--sui-sp-3 );
591+ margin-left : var (--sui-sp-4 );
592+ flex-wrap : wrap ;
593+ }
594+ .agents-tag-filter-label {
595+ font-size : var (--sui-fs-sm );
596+ color : var (--sui-fg-muted );
597+ }
555598
556599/* Detail tabs */
557600.agent-tab-bar {
@@ -687,5 +730,7 @@ html[data-theme="dark"] .agent-type-acp { background: #134e4a; color: #5eead4; }
687730html [data-theme = " dark" ] .config-badge-id { background : #0c4a6e ; color : #7dd3fc ; }
688731html [data-theme = " dark" ] .config-badge-info { background : #1e3a5f ; color : #93c5fd ; }
689732html [data-theme = " dark" ] .config-badge-warn { background : #422006 ; color : #fcd34d ; }
733+ html [data-theme = " dark" ] .config-badge-tag { background : #334155 ; color : #cbd5e1 ; }
734+ html [data-theme = " dark" ] .config-badge-tag-active { background : #e5e7eb ; color : #1f2937 ; }
690735html [data-theme = " dark" ] .acp-command { color : #5eead4 ; }
691736 </style >
0 commit comments