Explorar el Código

fix: 修改选项获取接口

jiaxing.liao hace 1 semana
padre
commit
6be2d2370e

+ 2 - 2
apps/web/src/components/Chat/AiUiCard.vue

@@ -3,8 +3,8 @@
 		v-if="shouldShowFallback"
 		class="ai-ui-card-result"
 		icon="error"
-		title="404"
-		sub-title="卡片加载失败"
+		title=""
+		sub-title="不支持卡片展示"
 	/>
 	<iframe
 		v-else

+ 236 - 0
apps/web/src/features/SelectAgentModal.vue

@@ -0,0 +1,236 @@
+<template>
+	<el-dialog
+		v-model="visible"
+		v-loading="loadingConfig"
+		element-loading-text="获取配置中..."
+		title="选择智能体"
+		width="640px"
+		append-to-body
+		@close="handleClose"
+	>
+		<div class="agent-picker">
+			<el-input v-model="keyword" clearable placeholder="搜索智能体" @keyup.enter="handleSearch">
+				<template #append>
+					<el-button @click="handleSearch">搜索</el-button>
+				</template>
+			</el-input>
+			<el-scrollbar class="agent-picker__list">
+				<div v-loading="loading" class="agent-list">
+					<el-empty v-if="!agentOptions.length && !loading" description="暂无智能体" />
+					<div
+						v-for="item in agentOptions"
+						:key="item.id"
+						class="agent-option"
+						:class="{ 'agent-option--active': selectedAgentId === item.id }"
+						@click="handleSelectAgent(item)"
+					>
+						<div class="agent-option__left">
+							<div class="agent-option__avatar">{{ getAgentAvatar(item.avatar) }}</div>
+							<div class="agent-option__main">
+								<div class="agent-option__name">{{ item.name || '未命名智能体' }}</div>
+								<div class="agent-option__desc">{{ item.description || '暂无描述' }}</div>
+							</div>
+						</div>
+						<el-tag size="small" effect="plain">{{ formatModeLabel(item.mode) }}</el-tag>
+					</div>
+				</div>
+			</el-scrollbar>
+			<el-pagination
+				:page-size="pageSize"
+				:total="totalCount"
+				:current-page="currentPage"
+				@current-change="handlePageChange"
+				class="agent-pagination"
+			/>
+		</div>
+		<template #footer>
+			<el-button @click="handleClose">关闭</el-button>
+		</template>
+	</el-dialog>
+</template>
+
+<script setup lang="ts">
+import { ref, watch } from 'vue'
+import { agentApplication } from '@repo/api-service'
+import { ElMessage } from 'element-plus'
+
+type AgentOption = NonNullable<
+	Awaited<ReturnType<typeof agentApplication.postAiAgentPageList>>['result']
+>['model'][number]
+
+interface Props {
+	modelValue: boolean
+}
+
+interface Emits {
+	(e: 'update:modelValue', value: boolean): void
+	(e: 'select', agent: AgentOption, config: any): void
+}
+
+const props = defineProps<Props>()
+const emit = defineEmits<Emits>()
+
+const visible = ref(props.modelValue)
+const loading = ref(false)
+const loadingConfig = ref(false)
+const keyword = ref('')
+const agentOptions = ref<AgentOption[]>([])
+const selectedAgentId = ref('')
+const currentPage = ref(1)
+const pageSize = ref(20)
+const totalCount = ref(0)
+
+const formatModeLabel = (mode?: string) => {
+	if (mode === 'quick-answer') return '快速问答'
+	if (mode === 'smart-reasoning') return '智能推理'
+	return mode || '未知模式'
+}
+
+const getAgentAvatar = (avatar?: string) => avatar?.trim() || '🤖'
+
+const fetchAgentOptions = async (page = 1) => {
+	loading.value = true
+	try {
+		const res = await agentApplication.postAiAgentPageList({
+			keyword: keyword.value.trim(),
+			mode: '',
+			type: '',
+			pageIndex: page,
+			pageSize: pageSize.value
+		})
+		if (res?.isSuccess && res.result) {
+			agentOptions.value = res.result.model || []
+			totalCount.value = res.result.totalCount || 0
+			currentPage.value = page
+		}
+	} finally {
+		loading.value = false
+	}
+}
+
+const handleSearch = () => {
+	fetchAgentOptions(1)
+}
+
+const handlePageChange = (page: number) => {
+	fetchAgentOptions(page)
+}
+
+const handleSelectAgent = async (item: AgentOption) => {
+	selectedAgentId.value = item.id || ''
+	try {
+		loadingConfig.value = true
+		// 获取选择agent的配置
+		const res = await agentApplication.postAiAgentInfo({ id: item.id! })
+		if (res.isSuccess && res.result) {
+			emit('select', item, res.result.config)
+			ElMessage.success('设置成功')
+			handleClose()
+		} else {
+			ElMessage.error('获取配置失败')
+		}
+	} finally {
+		loadingConfig.value = false
+	}
+}
+
+const handleClose = () => {
+	visible.value = false
+	emit('update:modelValue', false)
+}
+
+watch(
+	() => props.modelValue,
+	(val) => {
+		visible.value = val
+		if (val && !agentOptions.value.length) {
+			fetchAgentOptions(1)
+		}
+	}
+)
+
+watch(visible, (val) => {
+	emit('update:modelValue', val)
+})
+</script>
+
+<style scoped lang="less">
+.agent-picker {
+	display: flex;
+	flex-direction: column;
+	gap: 12px;
+}
+
+.agent-picker__list {
+	height: 360px;
+}
+
+.agent-list {
+	min-height: 220px;
+}
+
+.agent-option {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	gap: 12px;
+	padding: 12px;
+	border: 1px solid var(--border-light);
+	border-radius: 8px;
+	cursor: pointer;
+}
+
+.agent-option + .agent-option {
+	margin-top: 8px;
+}
+
+.agent-option:hover,
+.agent-option--active {
+	border-color: var(--el-color-primary);
+	background: var(--el-color-primary-light-9);
+}
+
+.agent-option__left {
+	display: flex;
+	align-items: center;
+	gap: 10px;
+	min-width: 0;
+}
+
+.agent-option__avatar {
+	display: inline-flex;
+	align-items: center;
+	justify-content: center;
+	width: 32px;
+	height: 32px;
+	flex-shrink: 0;
+	font-size: 20px;
+	line-height: 1;
+	border-radius: 50%;
+	background: var(--bg-container);
+}
+
+.agent-option__main {
+	min-width: 0;
+}
+
+.agent-option__name {
+	font-size: 14px;
+	font-weight: 700;
+	color: var(--text-primary);
+}
+
+.agent-option__desc {
+	margin-top: 4px;
+	font-size: 12px;
+	color: var(--text-tertiary);
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+}
+
+.agent-pagination {
+	margin-top: 12px;
+	justify-content: center;
+}
+</style>

+ 10 - 173
apps/web/src/nodes/src/ai-agent/setter.vue

@@ -65,51 +65,11 @@
 		</div>
 	</el-scrollbar>
 
-	<el-dialog
+	<!-- 智能体选择弹窗 -->
+	<SelectAgentModal
 		v-model="agentPickerVisible"
-		v-loading="loadingAgentConfig"
-		element-loading-text="获取配置中..."
-		title="选择智能体"
-		width="640px"
-		append-to-body
-	>
-		<div class="agent-picker">
-			<el-input
-				v-model="agentKeyword"
-				clearable
-				placeholder="搜索智能体"
-				@keyup.enter="fetchAgentOptions"
-			>
-				<template #append>
-					<el-button @click="fetchAgentOptions">搜索</el-button>
-				</template>
-			</el-input>
-			<el-scrollbar class="agent-picker__list">
-				<div v-loading="agentLoading" class="agent-list">
-					<el-empty v-if="!agentOptions.length && !agentLoading" description="暂无智能体" />
-					<div
-						v-for="item in agentOptions"
-						:key="item.id"
-						class="agent-option"
-						:class="{ 'agent-option--active': selectedAgentId === item.id }"
-						@click="selectAgent(item)"
-					>
-						<div class="agent-option__left">
-							<div class="agent-option__avatar">{{ getAgentAvatar(item.avatar) }}</div>
-							<div class="agent-option__main">
-								<div class="agent-option__name">{{ item.name || '未命名智能体' }}</div>
-								<div class="agent-option__desc">{{ item.description || '暂无描述' }}</div>
-							</div>
-						</div>
-						<el-tag size="small" effect="plain">{{ formatModeLabel(item.mode) }}</el-tag>
-					</div>
-				</div>
-			</el-scrollbar>
-		</div>
-		<template #footer>
-			<el-button @click="agentPickerVisible = false">关闭</el-button>
-		</template>
-	</el-dialog>
+		@select="handleAgentSelect"
+	/>
 
 	<!-- 智能体编辑 -->
 	<AgentEditModal
@@ -123,9 +83,7 @@
 
 <script setup lang="ts">
 import { onMounted, ref } from 'vue'
-import { agentApplication } from '@repo/api-service'
 import { Operation, Check } from '@element-plus/icons-vue'
-import { ElMessage } from 'element-plus'
 
 import NodeRuntimeConfig from '@/nodes/_base/NodeRuntimeConfig.vue'
 import VarInput from '@/nodes/_base/VarInput.vue'
@@ -137,9 +95,10 @@ import {
 	type AiAgentMode
 } from './index'
 import AgentEditModal from '@/views/agent/components/EditModal.vue'
+import SelectAgentModal from '@/features/SelectAgentModal.vue'
 
 type AgentOption = NonNullable<
-	Awaited<ReturnType<typeof agentApplication.postAiAgentPageList>>['result']
+	Awaited<ReturnType<typeof import('@repo/api-service').agentApplication.postAiAgentPageList>>['result']
 >['model'][number]
 
 const props = defineProps<{
@@ -152,12 +111,7 @@ const emit = defineEmits<{
 
 const formData = useSetterModel<AiAgentData>(props, emit)
 const agentPickerVisible = ref(false)
-const agentLoading = ref(false)
-const agentKeyword = ref('')
-const agentOptions = ref<AgentOption[]>([])
-const selectedAgentId = ref('')
 const agentEditVisible = ref(false)
-const loadingAgentConfig = ref(false)
 
 const ensureDefaults = () => {
 	formData.value.mode = formData.value.mode || 'smart-reasoning'
@@ -167,35 +121,8 @@ const ensureDefaults = () => {
 		: DEFAULT_AI_AGENT_OUTPUTS
 }
 
-const formatModeLabel = (mode?: string) => {
-	if (mode === 'quick-answer') return '快速问答'
-	if (mode === 'smart-reasoning') return '智能推理'
-	return mode || '未知模式'
-}
-
-const getAgentAvatar = (avatar?: string) => avatar?.trim() || '🤖'
-
-const fetchAgentOptions = async () => {
-	agentLoading.value = true
-	try {
-		const res = await agentApplication.postAiAgentPageList({
-			keyword: agentKeyword.value.trim(),
-			mode: '',
-			type: '',
-			pageIndex: 1,
-			pageSize: 20
-		})
-		agentOptions.value = res?.isSuccess ? res.result?.model || [] : []
-	} finally {
-		agentLoading.value = false
-	}
-}
-
-const openAgentPicker = async () => {
+const openAgentPicker = () => {
 	agentPickerVisible.value = true
-	if (!agentOptions.value.length) {
-		await fetchAgentOptions()
-	}
 }
 
 const openEditModal = () => {
@@ -210,29 +137,13 @@ const handleAgentConfigConfirm = (payload: {
 	formData.value.agent_config = payload.config || {}
 }
 
-const selectAgent = async (item: AgentOption) => {
-	console.log('selectAgent', item)
-	selectedAgentId.value = item.id || ''
-	try {
-		loadingAgentConfig.value = true
-		// 获取选择agent的配置
-		const res = await agentApplication.postAiAgentInfo({ id: item.id! })
-		if (res.isSuccess && res.result) {
-			formData.value.mode = (item.mode as AiAgentMode) || 'smart-reasoning'
-			formData.value.agent_config = res.result.config
-			ElMessage.success('设置成功')
-			agentPickerVisible.value = false
-		} else {
-			ElMessage.error('获取配置失败')
-		}
-	} finally {
-		loadingAgentConfig.value = false
-	}
+const handleAgentSelect = (item: AgentOption, config: any) => {
+	formData.value.mode = (item.mode as AiAgentMode) || 'smart-reasoning'
+	formData.value.agent_config = config
 }
 
 onMounted(async () => {
 	ensureDefaults()
-	await fetchAgentOptions()
 })
 </script>
 
@@ -318,78 +229,4 @@ onMounted(async () => {
 	font-size: 12px;
 	color: var(--text-tertiary);
 }
-
-.agent-picker {
-	display: flex;
-	flex-direction: column;
-	gap: 12px;
-}
-
-.agent-picker__list {
-	height: 360px;
-}
-
-.agent-list {
-	min-height: 220px;
-}
-
-.agent-option {
-	display: flex;
-	align-items: center;
-	justify-content: space-between;
-	gap: 12px;
-	padding: 12px;
-	border: 1px solid var(--border-light);
-	border-radius: 8px;
-	cursor: pointer;
-}
-
-.agent-option + .agent-option {
-	margin-top: 8px;
-}
-
-.agent-option:hover,
-.agent-option--active {
-	border-color: var(--el-color-primary);
-	background: var(--el-color-primary-light-9);
-}
-
-.agent-option__left {
-	display: flex;
-	align-items: center;
-	gap: 10px;
-	min-width: 0;
-}
-
-.agent-option__avatar {
-	display: inline-flex;
-	align-items: center;
-	justify-content: center;
-	width: 32px;
-	height: 32px;
-	flex-shrink: 0;
-	font-size: 20px;
-	line-height: 1;
-	border-radius: 50%;
-	background: var(--bg-container);
-}
-
-.agent-option__main {
-	min-width: 0;
-}
-
-.agent-option__name {
-	font-size: 14px;
-	font-weight: 700;
-	color: var(--text-primary);
-}
-
-.agent-option__desc {
-	margin-top: 4px;
-	font-size: 12px;
-	color: var(--text-tertiary);
-	overflow: hidden;
-	text-overflow: ellipsis;
-	white-space: nowrap;
-}
 </style>

+ 6 - 10
apps/web/src/nodes/src/knowledge-retrieval/setter.vue

@@ -204,15 +204,13 @@ const mergeSelectedOptions = (options: SelectOption[], selectedValues: string[])
 const fetchKnowledgeBaseOptions = async () => {
 	knowledgeBaseLoading.value = true
 	try {
-		const res = await knowledge.postAiKnowledgeBasePageList({
+		const res = await knowledge.postAiKnowledgeBaseSelectList({
 			keyword: '',
-			type: '',
-			pageIndex: 1,
-			pageSize: 20
+			type: ''
 		})
 		if (!res?.isSuccess) return
 
-		const list = (res.result?.model || []).map((item) => ({
+		const list = (res.result || []).map((item) => ({
 			label: normalizeOptionLabel(item),
 			value: normalizeOptionValue(item),
 			raw: item
@@ -245,12 +243,10 @@ const fetchKnowledgeOptions = async (baseIdsInput?: string[]) => {
 	try {
 		const results = await Promise.all(
 			baseIds.map((knowledgeBaseId) =>
-				knowledge.postAiKnowledgePageList({
+				knowledge.postAiKnowledgeSelectList({
 					knowledge_base_id: knowledgeBaseId,
 					title: '',
-					file_type: '',
-					pageIndex: 1,
-					pageSize: knowledgePageSize
+					file_type: ''
 				})
 			)
 		)
@@ -259,7 +255,7 @@ const fetchKnowledgeOptions = async (baseIdsInput?: string[]) => {
 		results.forEach((res) => {
 			if (!res?.isSuccess) return
 			console.log(res.result)
-			;(res.result?.model || []).forEach((item) => {
+			;(res.result || []).forEach((item) => {
 				if (!item.id) return
 				optionMap.set(item.id, {
 					label: normalizeOptionLabel(item),

+ 6 - 11
apps/web/src/nodes/src/llm/setter.vue

@@ -13,8 +13,8 @@ import StructModal from './StructModal.vue'
 import type { LLMData, LLMPromptItem } from './index'
 
 type LLMModelItem = NonNullable<
-	Awaited<ReturnType<typeof aiModel.postModelPageList>>['result']
->['model'][number]
+	Awaited<ReturnType<typeof aiModel.postModelSelectList>>['result']
+>[number]
 
 const props = defineProps<{
 	data: LLMData
@@ -53,8 +53,6 @@ const handleSchemaClose = () => {
 	structModalVisible.value = false
 }
 
-const modelLabel = (item: LLMModelItem) => (item.title ? `${item.title} (${item.name})` : item.name)
-
 const formatSchemaType = (schema: any) => {
 	if (schema?.type === 'array') {
 		const itemType = schema.items?.type || 'string'
@@ -94,15 +92,12 @@ const structuredPreviewTree = computed(() =>
 )
 
 const fetchChatModels = async (keyword = '') => {
-	const res = await aiModel.postModelPageList({
+	const res = await aiModel.postModelSelectList({
 		keyword: keyword.trim(),
-		type: 'KnowledgeQA',
-		source: '',
-		pageIndex: 1,
-		pageSize: 20
+		type: 'KnowledgeQA'
 	})
 	if (res?.isSuccess) {
-		const nextModels = (res.result?.model || []) as LLMModelItem[]
+		const nextModels = (res.result || []) as LLMModelItem[]
 		chatModels.value = nextModels
 	}
 }
@@ -164,7 +159,7 @@ onMounted(async () => {
 						<el-option
 							v-for="model in chatModels"
 							:key="model.id"
-							:label="modelLabel(model)"
+							:label="model.title"
 							:value="model.id"
 						/>
 					</el-select>

+ 6 - 14
apps/web/src/nodes/src/question-classifier/setter.vue

@@ -23,7 +23,7 @@
 						<el-option
 							v-for="model in chatModels"
 							:key="model.id"
-							:label="modelLabel(model)"
+							:label="model.title"
 							:value="model.id"
 						/>
 					</el-select>
@@ -151,8 +151,8 @@ import { aiModel } from '@repo/api-service'
 import type { QuestionClassifierData, ClassItem } from './index'
 
 type QuestionClassifierModelItem = NonNullable<
-	Awaited<ReturnType<typeof aiModel.postModelPageList>>['result']
->['model'][number]
+	Awaited<ReturnType<typeof aiModel.postModelSelectList>>['result']
+>[number]
 
 interface Emits {
 	(e: 'update', value: QuestionClassifierData): void
@@ -187,11 +187,6 @@ const formData = useSetterModel<QuestionClassifierData>(props, emit)
 const chatModels = ref<QuestionClassifierModelItem[]>([])
 const modelsLoading = ref(false)
 
-const modelLabel = (item: QuestionClassifierModelItem) => {
-	const title = item.title?.trim()
-	return title ? `${title} (${item.name})` : item.name
-}
-
 const mergeModels = (items: QuestionClassifierModelItem[]) => {
 	const modelMap = new Map<string, QuestionClassifierModelItem>()
 	chatModels.value.forEach((item) => {
@@ -213,15 +208,12 @@ const hydrateSelectedModel = async () => {
 }
 
 const fetchChatModels = async (keyword = '') => {
-	const res = await aiModel.postModelPageList({
+	const res = await aiModel.postModelSelectList({
 		keyword: keyword.trim(),
-		type: 'KnowledgeQA',
-		source: '',
-		pageIndex: 1,
-		pageSize: 50
+		type: 'KnowledgeQA'
 	})
 	if (res?.isSuccess) {
-		mergeModels((res.result?.model || []) as QuestionClassifierModelItem[])
+		mergeModels((res.result || []) as QuestionClassifierModelItem[])
 	}
 }
 

+ 310 - 0
apps/web/src/views/agent/components/DetailModal.vue

@@ -0,0 +1,310 @@
+<template>
+	<el-dialog
+		:model-value="modelValue"
+		:title="t('pages.agent.agentDetail')"
+		width="760px"
+		destroy-on-close
+		@update:model-value="emit('update:modelValue', $event)"
+	>
+		<div v-if="detailItem" class="detail-modal">
+			<div class="hero">
+				<div class="hero__avatar">{{ detailItem.avatar?.trim() || '🤖' }}</div>
+				<div class="hero__content">
+					<div class="hero__title">
+						{{ detailItem.name || t('pages.agent.unnamedAgent') }}
+					</div>
+					<div class="hero__meta">
+						<el-tag effect="plain">{{ formatModeLabel(detailItem.mode) }}</el-tag>
+						<el-tag type="info" effect="plain">{{ formatTypeLabel(detailItem.type) }}</el-tag>
+						<el-tag
+							v-if="detailItem.is_builtin"
+							type="success"
+							effect="plain"
+						>
+							Built-in
+						</el-tag>
+					</div>
+					<div class="hero__desc">
+						{{ detailItem.description || t('pages.agent.noDescription') }}
+					</div>
+				</div>
+			</div>
+
+			<div class="section">
+				<div class="section__title">基础信息</div>
+				<div class="info-grid">
+					<div v-for="item in basicItems" :key="item.label" class="info-card">
+						<div class="info-card__label">{{ item.label }}</div>
+						<div class="info-card__value">{{ item.value }}</div>
+					</div>
+				</div>
+			</div>
+
+			<div class="section">
+				<div class="section__title">配置摘要</div>
+				<div class="info-grid">
+					<div v-for="item in configItems" :key="item.label" class="info-card">
+						<div class="info-card__label">{{ item.label }}</div>
+						<div class="info-card__value">{{ item.value }}</div>
+					</div>
+				</div>
+			</div>
+
+			<div v-if="promptItems.length" class="section">
+				<div class="section__title">提示词</div>
+				<div class="prompt-list">
+					<div v-for="item in promptItems" :key="item.label" class="prompt-card">
+						<div class="prompt-card__head">{{ item.label }}</div>
+						<pre class="prompt-card__body">{{ item.value }}</pre>
+					</div>
+				</div>
+			</div>
+		</div>
+	</el-dialog>
+</template>
+
+<script setup lang="ts">
+import { computed } from 'vue'
+import { useI18n } from '@/composables/useI18n'
+import type { AgentItem } from '../type'
+
+const props = defineProps<{
+	modelValue: boolean
+	detailItem: AgentItem | null
+	modelNameMap: Record<string, string>
+}>()
+
+const emit = defineEmits<{
+	'update:modelValue': [value: boolean]
+}>()
+
+const { t } = useI18n()
+
+function formatModeLabel(mode?: string) {
+	if (mode === 'quick-answer') return t('pages.agent.modeQuickAnswer')
+	if (mode === 'smart-reasoning') return t('pages.agent.modeSmartReasoning')
+	if (mode === 'agent') return 'Agent'
+	return t('pages.agent.modeUnset')
+}
+
+function formatTypeLabel(type?: string) {
+	if (type === 'knowledgeqa') return 'Knowledge'
+	if (type === 'agent') return 'Agent'
+	return type || '-'
+}
+
+function formatBoolean(value?: boolean) {
+	return value ? '开启' : '关闭'
+}
+
+function formatModelName(id?: string) {
+	if (!id) return '-'
+	return props.modelNameMap[id] || id
+}
+
+const basicItems = computed(() => {
+	const item = props.detailItem
+	if (!item) return []
+
+	return [
+		{ label: '模型', value: formatModelName(item.config?.model_config?.model_id) },
+		{ label: '重排模型', value: formatModelName(item.config?.model_config?.rerank_model_id) },
+		{ label: 'VLM 模型', value: formatModelName(item.config?.img_vlm_config?.vlm_model_id) },
+		{ label: 'ASR 模型', value: formatModelName(item.config?.img_vlm_config?.asr_model_id) },
+		{ label: '创建时间', value: item.creationTime || '-' },
+		{ label: '更新时间', value: item.updateTime || '-' }
+	]
+})
+
+const configItems = computed(() => {
+	const item = props.detailItem
+	if (!item) return []
+
+	return [
+		{ label: '温度', value: `${item.config?.model_config?.temperature ?? '-'}` },
+		{
+			label: '最大 Token',
+			value: `${item.config?.model_config?.max_completion_tokens ?? '-'}`
+		},
+		{ label: '思考模式', value: formatBoolean(item.config?.model_config?.thinking) },
+		{
+			label: '多轮对话',
+			value: formatBoolean(item.config?.multiple_config?.multi_turn_enabled)
+		},
+		{
+			label: '知识库数量',
+			value: `${item.config?.kb_config?.knowledge_bases?.length ?? 0}`
+		},
+		{
+			label: '工具数量',
+			value: `${item.config?.setting_config?.allowed_tools?.length ?? 0}`
+		}
+	]
+})
+
+const promptItems = computed(() => {
+	const item = props.detailItem
+	if (!item) return []
+
+	return [
+		{
+			label: '系统提示词',
+			value: item.config?.basic_config?.system_prompt || ''
+		},
+		{
+			label: '上下文模板',
+			value: item.config?.basic_config?.context_template || ''
+		},
+		{
+			label: '改写系统提示词',
+			value: item.config?.advanced_config?.rewrite_prompt_system || ''
+		},
+		{
+			label: '改写用户提示词',
+			value: item.config?.advanced_config?.rewrite_prompt_user || ''
+		},
+		{
+			label: '兜底提示词',
+			value: item.config?.advanced_config?.fallback_prompt || ''
+		}
+	].filter((entry) => entry.value.trim())
+})
+</script>
+
+<style scoped lang="less">
+.detail-modal {
+	display: flex;
+	flex-direction: column;
+	gap: 20px;
+}
+
+.hero {
+	display: flex;
+	gap: 16px;
+	padding: 18px;
+	border: 1px solid var(--border-light);
+	border-radius: 18px;
+	background: var(--bg-base);
+}
+
+.hero__avatar {
+	width: 72px;
+	height: 72px;
+	flex-shrink: 0;
+	border-radius: 20px;
+	display: grid;
+	place-items: center;
+	font-size: 34px;
+	background: var(--bg-overlay);
+}
+
+.hero__content {
+	min-width: 0;
+	display: flex;
+	flex-direction: column;
+	gap: 10px;
+}
+
+.hero__title {
+	font-size: 22px;
+	font-weight: 700;
+	color: var(--text-strong);
+	word-break: break-word;
+}
+
+.hero__meta {
+	display: flex;
+	flex-wrap: wrap;
+	gap: 8px;
+}
+
+.hero__desc {
+	color: var(--text-secondary);
+	line-height: 1.7;
+	white-space: pre-wrap;
+	word-break: break-word;
+}
+
+.section {
+	display: flex;
+	flex-direction: column;
+	gap: 12px;
+}
+
+.section__title {
+	font-size: 15px;
+	font-weight: 700;
+	color: var(--text-strong);
+}
+
+.info-grid {
+	display: grid;
+	grid-template-columns: repeat(2, minmax(0, 1fr));
+	gap: 12px;
+}
+
+.info-card {
+	padding: 14px 16px;
+	border: 1px solid var(--border-light);
+	border-radius: 14px;
+	background: var(--bg-base);
+}
+
+.info-card__label {
+	font-size: 12px;
+	color: var(--text-tertiary);
+}
+
+.info-card__value {
+	margin-top: 6px;
+	font-size: 14px;
+	line-height: 1.6;
+	color: var(--text-primary);
+	word-break: break-word;
+}
+
+.prompt-list {
+	display: flex;
+	flex-direction: column;
+	gap: 12px;
+}
+
+.prompt-card {
+	border: 1px solid var(--border-light);
+	border-radius: 14px;
+	background: var(--bg-base);
+	overflow: hidden;
+}
+
+.prompt-card__head {
+	padding: 12px 14px;
+	border-bottom: 1px solid var(--border-light);
+	font-size: 13px;
+	font-weight: 600;
+	color: var(--text-secondary);
+	background: var(--bg-overlay);
+}
+
+.prompt-card__body {
+	margin: 0;
+	padding: 14px;
+	max-height: 280px;
+	overflow: auto;
+	white-space: pre-wrap;
+	word-break: break-word;
+	font-size: 13px;
+	line-height: 1.7;
+	color: var(--text-primary);
+	font-family: Monaco, Consolas, 'Courier New', monospace;
+}
+
+@media (max-width: 768px) {
+	.hero {
+		flex-direction: column;
+	}
+
+	.info-grid {
+		grid-template-columns: 1fr;
+	}
+}
+</style>

+ 40 - 138
apps/web/src/views/agent/components/EditModal.vue

@@ -154,16 +154,13 @@
 								<el-select
 									v-model="form.config.model_config.model_id"
 									filterable
-									remote
 									reserve-keyword
-									:remote-method="searchChatModels"
-									:loading="chatModelsLoading"
 									style="width: 100%"
 								>
 									<el-option
 										v-for="model in chatModels"
 										:key="model.id"
-										:label="modelLabel(model)"
+										:label="model.title"
 										:value="model.id"
 									/>
 								</el-select>
@@ -251,16 +248,12 @@
 								<el-select
 									v-model="form.config.model_config.rerank_model_id"
 									filterable
-									remote
-									reserve-keyword
-									:remote-method="searchRerankModels"
-									:loading="rerankModelsLoading"
 									style="width: 100%"
 								>
 									<el-option
 										v-for="model in rerankModels"
 										:key="model.id"
-										:label="modelLabel(model)"
+										:label="model.title"
 										:value="model.id"
 									/>
 								</el-select>
@@ -567,9 +560,6 @@
 								<el-select
 									v-model="form.config.web_search_config.web_search_provider_id"
 									filterable
-									remote
-									reserve-keyword
-									:remote-method="searchWebSearchProviders"
 									:loading="webSearchProviderLoading"
 									clearable
 									placeholder="请输入关键词搜索"
@@ -647,16 +637,12 @@
 								<el-select
 									v-model="form.config.img_vlm_config.vlm_model_id"
 									filterable
-									remote
-									reserve-keyword
-									:remote-method="searchVlmModels"
-									:loading="vlmModelsLoading"
 									style="width: 100%"
 								>
 									<el-option
 										v-for="model in vlmModels"
 										:key="model.id"
-										:label="modelLabel(model)"
+										:label="model.title"
 										:value="model.id"
 									/>
 								</el-select>
@@ -678,17 +664,13 @@
 								<el-select
 									v-model="form.config.img_vlm_config.asr_model_id"
 									filterable
-									remote
-									reserve-keyword
-									:remote-method="searchAsrModels"
-									:loading="asrModelsLoading"
 									clearable
 									style="width: 100%"
 								>
 									<el-option
 										v-for="model in asrModels"
 										:key="model.id"
-										:label="modelLabel(model)"
+										:label="model.title"
 										:value="model.id"
 									/>
 								</el-select>
@@ -884,10 +866,6 @@ const formId = ref('')
 const submitLoading = ref(false)
 // 统一缓存各类模型选项,按 type 在计算属性中拆分使用。
 const modelOptions = ref<ModelItem[]>([])
-const chatModelsLoading = ref(false)
-const rerankModelsLoading = ref(false)
-const vlmModelsLoading = ref(false)
-const asrModelsLoading = ref(false)
 const kbOptions = ref<KnowledgeItem[]>([])
 const kbLoading = ref(false)
 const toolList = ref<
@@ -903,9 +881,7 @@ const toolList = ref<
 const webSearchProviderOptions = ref<AgentSelectOption[]>([])
 const webSearchProviderLoading = ref(false)
 const mcpServiceOptions = ref<AgentSelectOption[]>([])
-const mcpLoading = ref(false)
 const skillOptions = ref<AgentSelectOption[]>([])
-const skillLoading = ref(false)
 const allSkillOptions = ref<AgentSelectOption[]>([])
 const emojiDialogVisible = ref(false)
 const systemPromptInputRef = ref()
@@ -1040,9 +1016,7 @@ const vlmModels = computed(() => modelOptions.value.filter((item) => item.type =
 const asrModels = computed(() =>
 	modelOptions.value.filter((item) => ['ASR', 'Asr', 'asr'].includes(item.type || ''))
 )
-const modelPageSize = 20
 const remoteOptionPageSize = 20
-const checkboxOptionPageSize = 200
 const modelRequestKeyPrefix = 'agent-edit-models'
 const selectedEmoji = computed(() => form.avatar || '🙂')
 const knowledgeCheckboxOptions = computed<AgentSelectOption[]>(() => {
@@ -1110,10 +1084,6 @@ const fieldTabMap: Array<{ match: string | RegExp; tab: string }> = [
 	{ match: 'config.advanced_config.rewrite_prompt_user', tab: 'multi-turn' }
 ]
 
-function modelLabel(item: ModelItem) {
-	return item.title ? `${item.title} (${item.name})` : item.name
-}
-
 function resolveFieldTab(prop: string) {
 	for (const item of fieldTabMap) {
 		if (typeof item.match === 'string' && item.match === prop) return item.tab
@@ -1338,65 +1308,17 @@ function buildSubmitConfig() {
 }
 
 async function fetchModels(keyword = '', type = '') {
-	const res = await aiModel.postModelPageList(
+	const res = await aiModel.postModelSelectList(
 		{
 			keyword: keyword.trim(),
-			type,
-			source: '',
-			pageIndex: 1,
-			pageSize: modelPageSize
+			type
 		},
 		{
 			requestKey: `${modelRequestKeyPrefix}-${type || 'all'}`
 		}
 	)
 	if (res.isSuccess) {
-		modelOptions.value = mergeModelOptions((res.result?.model || []) as ModelItem[])
-	}
-}
-
-async function loadModels() {
-	await Promise.all([
-		fetchModels('', 'KnowledgeQA'),
-		fetchModels('', 'Rerank'),
-		fetchModels('', 'VLLM'),
-		fetchModels('', 'ASR')
-	])
-}
-
-async function searchChatModels(keyword: string) {
-	chatModelsLoading.value = true
-	try {
-		await fetchModels(keyword, 'KnowledgeQA')
-	} finally {
-		chatModelsLoading.value = false
-	}
-}
-
-async function searchRerankModels(keyword: string) {
-	rerankModelsLoading.value = true
-	try {
-		await fetchModels(keyword, 'Rerank')
-	} finally {
-		rerankModelsLoading.value = false
-	}
-}
-
-async function searchVlmModels(keyword: string) {
-	vlmModelsLoading.value = true
-	try {
-		await fetchModels(keyword, 'VLLM')
-	} finally {
-		vlmModelsLoading.value = false
-	}
-}
-
-async function searchAsrModels(keyword: string) {
-	asrModelsLoading.value = true
-	try {
-		await fetchModels(keyword, 'ASR')
-	} finally {
-		asrModelsLoading.value = false
+		modelOptions.value = mergeModelOptions((res.result || []) as ModelItem[])
 	}
 }
 
@@ -1542,21 +1464,17 @@ function applyDetail(item: AgentItem) {
 	form.config.advanced_config.fallback_response =
 		item.config?.advanced_config?.fallback_response || ''
 	form.config.advanced_config.fallback_prompt = item.config?.advanced_config?.fallback_prompt || ''
-
-	console.log('applyDetail', item, form)
 }
 
 async function loadKnowledgeBases() {
 	kbLoading.value = true
 	try {
-		const res = await knowledge.postAiKnowledgeBasePageList({
+		const res = await knowledge.postAiKnowledgeBaseSelectList({
 			keyword: '',
-			type: '',
-			pageIndex: 1,
-			pageSize: checkboxOptionPageSize
+			type: ''
 		})
 		if (res.isSuccess) {
-			kbOptions.value = mergeKnowledgeOptions((res.result?.model || []) as KnowledgeItem[])
+			kbOptions.value = mergeKnowledgeOptions((res.result || []) as KnowledgeItem[])
 		}
 	} finally {
 		kbLoading.value = false
@@ -1585,11 +1503,8 @@ async function loadWebSearchProviders() {
 async function searchWebSearchProviders(keyword: string) {
 	webSearchProviderLoading.value = true
 	try {
-		const res = await resource.postWebSearchPageList({
-			keyword: keyword.trim(),
-			provider: '',
-			pageIndex: 1,
-			pageSize: remoteOptionPageSize
+		const res = await resource.postWebSearchSelectList({
+			keyword: keyword.trim()
 		})
 		if (res?.isSuccess) {
 			webSearchProviderOptions.value = mergeOptions(
@@ -1613,49 +1528,36 @@ async function loadMcpServices() {
 }
 
 async function searchMcpServices(keyword: string) {
-	mcpLoading.value = true
-	try {
-		const res = await resource.postMcpPageList({
-			keyword: keyword.trim(),
-			transport_type: '',
-			pageIndex: 1,
-			pageSize: keyword.trim() ? remoteOptionPageSize : checkboxOptionPageSize
-		})
-		if (res?.isSuccess) {
-			mcpServiceOptions.value = mergeOptions(
-				mcpServiceOptions.value,
-				((res.result?.model || []) as McpItem[])
-					.filter((item): item is McpItem & { id: string } => !!item.id)
-					.map((item) => ({
-						label: item.name || item.id,
-						value: item.id
-					})),
-				form.config.setting_config.mcp_services
-			)
-		}
-	} finally {
-		mcpLoading.value = false
+	const res = await resource.postMcpSelectList({
+		keyword: keyword.trim()
+	})
+	if (res?.isSuccess) {
+		mcpServiceOptions.value = mergeOptions(
+			mcpServiceOptions.value,
+			((res.result || []) as McpItem[])
+				.filter((item): item is McpItem & { id: string } => !!item.id)
+				.map((item) => ({
+					label: item.name || item.id,
+					value: item.id
+				})),
+			form.config.setting_config.mcp_services
+		)
 	}
 }
 
 async function loadSkills() {
-	skillLoading.value = true
-	try {
-		const res = await resource.postSkillsList({})
-		if (res?.isSuccess) {
-			allSkillOptions.value = ((res.result || []) as SkillItem[]).map((item) => ({
-				label: item.name,
-				value: item.name,
-				description: item.description
-			}))
-			skillOptions.value = mergeOptions(
-				skillOptions.value,
-				filterLocalOptions(allSkillOptions.value, ''),
-				form.config.setting_config.selected_skills
-			)
-		}
-	} finally {
-		skillLoading.value = false
+	const res = await resource.postSkillsList({})
+	if (res?.isSuccess) {
+		allSkillOptions.value = ((res.result || []) as SkillItem[]).map((item) => ({
+			label: item.name,
+			value: item.name,
+			description: item.description
+		}))
+		skillOptions.value = mergeOptions(
+			skillOptions.value,
+			filterLocalOptions(allSkillOptions.value, ''),
+			form.config.setting_config.selected_skills
+		)
 	}
 }
 
@@ -1669,7 +1571,6 @@ async function loadDetail(id: string) {
 }
 
 async function handleOpen() {
-	console.log('handleOpen', props.agentId)
 	loadTools()
 	if (props.configOnly) {
 		const initialMode =
@@ -1686,7 +1587,7 @@ async function handleOpen() {
 		resetForm()
 	}
 	await Promise.all([
-		loadModels(),
+		fetchModels(),
 		loadKnowledgeBases(),
 		loadWebSearchProviders(),
 		loadMcpServices(),
@@ -2073,6 +1974,7 @@ watch(
 		font-weight: 500;
 		line-height: 1.5;
 		color: var(--agent-text);
+		margin-top: -2px;
 	}
 
 	.tool-option__desc {

+ 68 - 34
apps/web/src/views/agent/index.vue

@@ -24,15 +24,26 @@
 		<el-card class="panel">
 			<div class="toolbar">
 				<div class="toolbar-left">
-					<el-input v-model="filters.keyword" clearable :placeholder="t('pages.agent.searchPlaceholder')" class="search-input"
-						@keyup.enter="handleSearch">
+					<el-input
+						v-model="filters.keyword"
+						clearable
+						:placeholder="t('pages.agent.searchPlaceholder')"
+						class="search-input"
+						@keyup.enter="handleSearch"
+					>
 						<template #prefix>
 							<el-icon>
 								<Search />
 							</el-icon>
 						</template>
 					</el-input>
-					<el-select v-model="filters.mode" clearable :placeholder="t('pages.agent.mode')" style="width: 160px" @change="handleSearch">
+					<el-select
+						v-model="filters.mode"
+						clearable
+						:placeholder="t('pages.agent.mode')"
+						style="width: 160px"
+						@change="handleSearch"
+					>
 						<el-option :label="t('pages.agent.modeQuickAnswer')" value="quick-answer" />
 						<el-option :label="t('pages.agent.modeSmartReasoning')" value="smart-reasoning" />
 					</el-select>
@@ -56,9 +67,13 @@
 			</div>
 
 			<div v-loading="loading" class="grid">
-				<el-empty v-if="!visibleList.length && !loading" :description="t('pages.agent.emptyDescription')" class="empty" />
+				<el-empty
+					v-if="!visibleList.length && !loading"
+					:description="t('pages.agent.emptyDescription')"
+					class="empty"
+				/>
 
-				<div v-for="item in visibleList" :key="item.id" class="card" @click="openDetail(item.id)">
+				<div v-for="item in visibleList" :key="item.id" class="card" @click="openDetail(item.id!)">
 					<div class="card-head">
 						<div class="emoji-avatar">{{ getAgentEmoji(item.avatar) }}</div>
 						<div class="card-head__content">
@@ -74,10 +89,14 @@
 										<template #dropdown>
 											<el-dropdown-menu>
 												<el-dropdown-item>
-													<el-button link type="primary" @click="openEditDrawer(item.id)">{{ t('common.edit') }}</el-button>
+													<el-button link type="primary" @click="openEditDrawer(item.id!)">{{
+														t('common.edit')
+													}}</el-button>
 												</el-dropdown-item>
 												<el-dropdown-item>
-													<el-button link type="danger" @click="removeItem(item.id)">{{ t('common.delete') }}</el-button>
+													<el-button link type="danger" @click="removeItem(item.id!)">{{
+														t('common.delete')
+													}}</el-button>
 												</el-dropdown-item>
 											</el-dropdown-menu>
 										</template>
@@ -105,10 +124,14 @@
 								<template #dropdown>
 									<el-dropdown-menu>
 										<el-dropdown-item>
-											<el-button link type="primary" @click="openEditDrawer(item.id)">{{ t('common.edit') }}</el-button>
+											<el-button link type="primary" @click="openEditDrawer(item.id!)">{{
+												t('common.edit')
+											}}</el-button>
 										</el-dropdown-item>
 										<el-dropdown-item>
-											<el-button link type="danger" @click="removeItem(item.id)">{{ t('common.delete') }}</el-button>
+											<el-button link type="danger" @click="removeItem(item.id!)">{{
+												t('common.delete')
+											}}</el-button>
 										</el-dropdown-item>
 									</el-dropdown-menu>
 								</template>
@@ -119,43 +142,35 @@
 			</div>
 
 			<div class="pagination" v-if="pagination.totalCount">
-				<el-pagination v-model:current-page="pagination.pageIndex" v-model:page-size="pagination.pageSize" background
+				<el-pagination
+					v-model:current-page="pagination.pageIndex"
+					v-model:page-size="pagination.pageSize"
+					background
 					layout="total, prev, pager, next"
-					:total="pagination.totalCount" @current-change="handlePageChange" @size-change="handleSizeChange" />
+					:total="pagination.totalCount"
+					@current-change="handlePageChange"
+					@size-change="handleSizeChange"
+				/>
 			</div>
 		</el-card>
 
 		<EditModal v-model="drawerVisible" :agent-id="currentId" @saved="handleSaved" />
-
-		<el-dialog v-model="detailVisible" :title="t('pages.agent.agentDetail')" width="720px">
-			<el-descriptions v-if="detailItem" :column="1" border>
-				<el-descriptions-item :label="t('pages.agent.nameLabel')">{{ detailItem.name }}</el-descriptions-item>
-				<el-descriptions-item :label="t('pages.agent.modeLabel')">{{ detailItem.mode }}</el-descriptions-item>
-				<el-descriptions-item :label="t('pages.agent.descriptionLabel')">{{
-					detailItem.description || '-'
-				}}</el-descriptions-item>
-				<el-descriptions-item :label="t('pages.agent.systemPromptLabel')">{{
-					detailItem.config?.basic_config?.system_prompt || '-'
-				}}</el-descriptions-item>
-				<el-descriptions-item :label="t('pages.agent.modelIdLabel')">{{
-					detailItem.config?.model_config?.model_id || '-'
-				}}</el-descriptions-item>
-			</el-descriptions>
-		</el-dialog>
+		<DetailModal v-model="detailVisible" :detail-item="detailItem" :model-name-map="modelNameMap" />
 	</div>
 </template>
 
 <script setup lang="ts">
 // 1. Type imports
-import type { AgentItem } from './type'
+import type { AgentItem, ModelItem } from './type'
 
 // 2. Composables
 import { computed, onMounted, reactive, ref } from 'vue'
 import { ElMessageBox } from 'element-plus'
 import { Plus, Search, MoreFilled, RefreshRight } from '@element-plus/icons-vue'
-import { agentApplication } from '@repo/api-service'
+import { agentApplication, aiModel } from '@repo/api-service'
 import { useI18n } from '@/composables/useI18n'
 import EditModal from './components/EditModal.vue'
+import DetailModal from './components/DetailModal.vue'
 
 const { t } = useI18n()
 
@@ -181,6 +196,7 @@ const filters = reactive({
 })
 
 const list = ref<AgentItem[]>([])
+const modelNameMap = ref<Record<string, string>>({})
 
 // 5. Computed properties
 const visibleList = computed(() => {
@@ -213,6 +229,21 @@ function formatTypeLabel(type?: string) {
 	return type || '-'
 }
 
+async function loadModelNameMap() {
+	const res = await aiModel.postModelSelectList({
+		keyword: '',
+		type: ''
+	})
+
+	const nextMap: Record<string, string> = {}
+	;(res?.result || []).forEach((item) => {
+		if (item.id) {
+			nextMap[item.id] = item.title || '-'
+		}
+	})
+	modelNameMap.value = nextMap
+}
+
 async function loadList(pageIndex = 1) {
 	loading.value = true
 	try {
@@ -283,7 +314,11 @@ function handleSaved() {
 
 async function removeItem(id: string) {
 	try {
-		await ElMessageBox.confirm(t('pages.agent.deleteConfirm'), t('pages.agent.deleteConfirmTitle'), { type: 'warning' })
+		await ElMessageBox.confirm(
+			t('pages.agent.deleteConfirm'),
+			t('pages.agent.deleteConfirmTitle'),
+			{ type: 'warning' }
+		)
 		await agentApplication.postAiAgentOpenApiDelete({ id })
 		loadList(pagination.pageIndex)
 	} catch {
@@ -293,7 +328,7 @@ async function removeItem(id: string) {
 
 // 7. Lifecycle
 onMounted(async () => {
-	await loadList(1)
+	await Promise.all([loadList(1), loadModelNameMap()])
 })
 </script>
 
@@ -549,8 +584,8 @@ onMounted(async () => {
 	font-variant-numeric: tabular-nums;
 }
 
-.body>.title,
-.body>.actions {
+.body > .title,
+.body > .actions {
 	display: none;
 }
 
@@ -566,7 +601,6 @@ onMounted(async () => {
 }
 
 @media (max-width: 768px) {
-
 	.page-head,
 	.toolbar,
 	.stats {

+ 10 - 17
apps/web/src/views/chat/api/chat.api.ts

@@ -114,15 +114,13 @@ export async function getSessionMessages(
 }
 
 export async function getAgentOptions(keyword = ''): Promise<ChatOptionItem[]> {
-	const res = await agentApplication.postAiAgentPageList({
+	const res = await agentApplication.postAiAgentSelectList({
 		keyword,
 		mode: '',
-		type: '',
-		pageIndex: 1,
-		pageSize: 100
+		type: ''
 	})
 
-	return (res.result?.model || []).map((item) => ({
+	return (res.result || []).map((item) => ({
 		label: item.name || item.id || '',
 		value: item.id || '',
 		description: item.description,
@@ -136,14 +134,12 @@ export async function getAgentInfo(id: string) {
 }
 
 export async function getKnowledgeBaseOptions(keyword = ''): Promise<ChatOptionItem[]> {
-	const res = await knowledge.postAiKnowledgeBasePageList({
+	const res = await knowledge.postAiKnowledgeBaseSelectList({
 		keyword,
-		type: '',
-		pageIndex: 1,
-		pageSize: 100
+		type: ''
 	})
 
-	return (res.result?.model || []).map((item) => ({
+	return (res.result || []).map((item) => ({
 		label: item.name || item.id || '',
 		value: item.id || '',
 		description: item.description,
@@ -153,16 +149,13 @@ export async function getKnowledgeBaseOptions(keyword = ''): Promise<ChatOptionI
 }
 
 export async function getModelOptions(keyword = '', type: string): Promise<ChatOptionItem[]> {
-	const res = await aiModel.postModelPageList({
+	const res = await aiModel.postModelSelectList({
 		keyword,
-		type,
-		source: '',
-		pageIndex: 1,
-		pageSize: 100
+		type
 	})
 
-	return (res.result?.model || []).map((item) => ({
-		label: item.title ? `${item.title} (${item.name})` : item.name || item.id || '',
+	return (res.result || []).map((item) => ({
+		label: item.title || '',
 		value: item.id || '',
 		description: item.description,
 		type: item.type,

+ 3 - 5
apps/web/src/views/chat/components/AddKbModal.vue

@@ -51,14 +51,12 @@ const rules = {
 
 const getKbOptions = async (keyword: string = '') => {
 	try {
-		const res = await knowledge.postAiKnowledgeBasePageList({
+		const res = await knowledge.postAiKnowledgeBaseSelectList({
 			keyword,
-			type: 'document',
-			pageIndex: 1,
-			pageSize: 20
+			type: 'document'
 		})
 		if (res.isSuccess)
-			knowledgeOptions.value = res.result.model.map((item) => ({
+			knowledgeOptions.value = (res.result || []).map((item) => ({
 				label: item.name,
 				value: item.id
 			}))

+ 4 - 9
apps/web/src/views/chat/index.vue

@@ -1045,12 +1045,9 @@ const fetchKnowledgeOptions = async (baseIds: string[]) => {
 
 	const results = await Promise.all(
 		baseIds.map((knowledgeBaseId) =>
-			knowledge.postAiKnowledgePageList({
+			knowledge.postAiKnowledgeSelectList({
 				knowledge_base_id: knowledgeBaseId,
-				title: '',
-				file_type: '',
-				pageIndex: 1,
-				pageSize: 20
+				title: ''
 			})
 		)
 	)
@@ -1058,10 +1055,10 @@ const fetchKnowledgeOptions = async (baseIds: string[]) => {
 	const optionMap: Record<string, { label: string; value: string }> = {}
 	results.forEach((res: any) => {
 		if (!res?.isSuccess) return
-		;(res.result?.model || []).forEach((item: any) => {
+		;(res.result || []).forEach((item: any) => {
 			if (!item.id) return
 			optionMap[item.id] = {
-				label: item.file_name!,
+				label: item.title!,
 				value: item.id
 			}
 		})
@@ -1111,7 +1108,6 @@ const handleSend = async (content?: string) => {
 	messages.value.push(userMsg)
 	await scrollToBottom()
 
-
 	const aiMsg = createAiMessage()
 	messages.value.push(aiMsg)
 	const aiMessageKey = aiMsg.key as string
@@ -1119,7 +1115,6 @@ const handleSend = async (content?: string) => {
 	activeStreamToken.value = streamToken
 	await scrollToBottom()
 
-
 	const getAiMessage = () => messages.value.find((item) => item.key === aiMessageKey)
 	const isActiveStream = () => activeStreamToken.value === streamToken
 

+ 17 - 24
apps/web/src/views/knowledge/components/KnowledgeBaseEditModal.vue

@@ -107,7 +107,7 @@
 									<el-option
 										v-for="item in summaryModels"
 										:key="item.id"
-										:label="buildModelLabel(item)"
+										:label="item.title"
 										:value="item.id"
 									/>
 								</el-select>
@@ -118,7 +118,7 @@
 									<el-option
 										v-for="item in embeddingModels"
 										:key="item.id"
-										:label="buildModelLabel(item)"
+										:label="item.title"
 										:value="item.id"
 									/>
 								</el-select>
@@ -193,7 +193,7 @@
 									<el-option
 										v-for="item in vlmModels"
 										:key="item.id"
-										:label="buildModelLabel(item)"
+										:label="item.title"
 										:value="item.id"
 									/>
 								</el-select>
@@ -226,7 +226,7 @@
 									<el-option
 										v-for="item in asrModels"
 										:key="item.id"
-										:label="buildModelLabel(item)"
+										:label="item.title"
 										:value="item.id"
 									/>
 								</el-select>
@@ -628,15 +628,12 @@ const asrModels = computed(() =>
 const isDocumentType = computed(() => form.type === 'document')
 
 async function fetchModels() {
-	const res = await aiModel.postModelPageList({
+	const res = await aiModel.postModelSelectList({
 		keyword: '',
-		type: '',
-		source: '',
-		pageIndex: 1,
-		pageSize: 200
+		type: ''
 	})
 	if (res?.isSuccess) {
-		modelList.value = (res.result?.model || []) as KnowledgeModelOption[]
+		modelList.value = (res.result || []) as KnowledgeModelOption[]
 		applyModelDefaults()
 	}
 }
@@ -655,12 +652,10 @@ async function fetchStorageProviders() {
 
 async function fetchVectorStores() {
 	try {
-		const res = await vector.postPageList({ keyword: '', pageIndex: 1, pageSize: 200 })
+		const res = await vector.postSelectList({ keyword: '' })
 		if (res?.isSuccess && res.result) {
-			const data = (res.result as any)?.model
-			const items = Array.isArray(data) ? data : data?.list || data?.items || data?.data || []
-			vectorStoreOptions.value = items.map((item: any) => ({
-				label: item.name || item.display_name || item.id,
+			vectorStoreOptions.value = res.result.map((item: any) => ({
+				label: `${item.name}${item.engine_type ? ` (${item.engine_type})` : ''}`,
 				value: item.id
 			}))
 		}
@@ -726,11 +721,6 @@ const rules = {
 	summary_model_id: [{ required: true, message: '请选择摘要模型', trigger: 'change' }]
 }
 
-function buildModelLabel(item: KnowledgeModelOption) {
-	const title = item.title?.trim()
-	return title ? `${title} (${item.name})` : item.name
-}
-
 function handleKnowledgeBaseTypeChange(type: KnowledgeBaseForm['type']) {
 	activeTab.value = 'basic'
 	if (type === 'faq') {
@@ -778,7 +768,10 @@ function handleOpen() {
 	activeTab.value = 'basic'
 }
 
-function openCreateDrawer() {
+async function openCreateDrawer() {
+	await fetchModels()
+	await fetchStorageProviders()
+	await fetchVectorStores()
 	editingId.value = ''
 	resetForm()
 	drawerVisible.value = true
@@ -841,6 +834,9 @@ async function openEditDrawer(id: string) {
 		wiki_max_pages_per_ingest: detail.wiki_config?.max_pages_per_ingest ?? 0,
 		wiki_synthesis_model_id: detail.wiki_config?.synthesis_model_id || ''
 	})
+	await fetchModels()
+	await fetchStorageProviders()
+	await fetchVectorStores()
 	await hydrateSelectedModels()
 	applyModelDefaults()
 	drawerVisible.value = true
@@ -971,9 +967,6 @@ defineExpose({
 })
 
 onMounted(async () => {
-	await fetchModels()
-	await fetchStorageProviders()
-	await fetchVectorStores()
 	resetForm()
 })
 </script>

+ 191 - 0
packages/api-service/schema/agent.openapi.json

@@ -5683,6 +5683,197 @@
 				"security": []
 			}
 		},
+		"/api/ai/agent/selectList": {
+			"post": {
+				"summary": "获取智能体选择列表",
+				"deprecated": false,
+				"description": "",
+				"tags": ["AgentApplication"],
+				"parameters": [
+					{
+						"name": "Authorization",
+						"in": "header",
+						"description": "",
+						"example": "bpm_client_1513029045627916288",
+						"schema": {
+							"type": "string",
+							"default": "bpm_client_1513029045627916288"
+						}
+					}
+				],
+				"requestBody": {
+					"content": {
+						"application/json": {
+							"schema": {
+								"type": "object",
+								"properties": {
+									"keyword": {
+										"type": "string"
+									},
+									"mode": {
+										"type": "string"
+									},
+									"type": {
+										"type": "string"
+									}
+								},
+								"required": []
+							},
+							"example": {
+								"keyword": "",
+								"mode": "quick-answer",
+								"type": "rag-qa"
+							}
+						}
+					},
+					"required": true
+				},
+				"responses": {
+					"200": {
+						"description": "",
+						"content": {
+							"application/json": {
+								"schema": {
+									"type": "object",
+									"properties": {
+										"isSuccess": {
+											"type": "boolean"
+										},
+										"code": {
+											"type": "integer"
+										},
+										"result": {
+											"type": "array",
+											"items": {
+												"type": "object",
+												"properties": {
+													"avatar": {
+														"type": "string"
+													},
+													"config": {
+														"type": "object",
+														"properties": {
+															"advanced_config": {
+																"type": "object",
+																"properties": {
+																	"enable_query_expansion": { "type": "boolean" },
+																	"enable_rewrite": { "type": "boolean" },
+																	"fallback_prompt": { "type": "string" },
+																	"fallback_response": { "type": "string" },
+																	"fallback_strategy": { "type": "string" },
+																	"rewrite_prompt_system": { "type": "string" },
+																	"rewrite_prompt_user": { "type": "string" }
+																},
+																"required": [
+																	"enable_query_expansion",
+																	"enable_rewrite",
+																	"fallback_prompt",
+																	"fallback_response",
+																	"fallback_strategy",
+																	"rewrite_prompt_system",
+																	"rewrite_prompt_user"
+																]
+															},
+															"basic_config": {
+																"type": "object",
+																"properties": {
+																	"agent_mode": { "type": "string" },
+																	"agent_type": { "type": "string" },
+																	"context_template": { "type": "string" },
+																	"suggested_prompts": {
+																		"type": "array",
+																		"items": { "type": "string" }
+																	},
+																	"system_prompt": { "type": "string" }
+																},
+																"required": [
+																	"agent_mode",
+																	"agent_type",
+																	"context_template",
+																	"suggested_prompts",
+																	"system_prompt"
+																]
+															},
+															"model_config": {
+																"type": "object",
+																"properties": {
+																	"max_completion_tokens": { "type": "integer" },
+																	"model_id": { "type": "string" },
+																	"temperature": { "type": "number" }
+																},
+																"required": ["max_completion_tokens", "model_id", "temperature"]
+															}
+														},
+														"required": ["advanced_config", "basic_config", "model_config"]
+													},
+													"creationTime": { "type": "string" },
+													"creatorUserId": { "type": "string" },
+													"description": { "type": "string" },
+													"id": { "type": "string" },
+													"isDeleted": { "type": "boolean" },
+													"is_builtin": { "type": "boolean" },
+													"mode": { "type": "string" },
+													"name": { "type": "string" },
+													"type": { "type": "string" },
+													"updateTime": { "type": "string" }
+												}
+											}
+										},
+										"isAuthorized": { "type": "boolean" }
+									},
+									"required": ["isSuccess", "code", "result", "isAuthorized"]
+								},
+								"example": {
+									"isSuccess": true,
+									"code": 1,
+									"result": [
+										{
+											"avatar": "",
+											"config": {
+												"advanced_config": {
+													"enable_query_expansion": true,
+													"enable_rewrite": true,
+													"fallback_prompt": "",
+													"fallback_response": "",
+													"fallback_strategy": "model",
+													"rewrite_prompt_system": "",
+													"rewrite_prompt_user": ""
+												},
+												"basic_config": {
+													"agent_mode": "quick-answer",
+													"agent_type": "rag-qa",
+													"context_template": "",
+													"suggested_prompts": [],
+													"system_prompt": ""
+												},
+												"model_config": {
+													"max_completion_tokens": 2048,
+													"model_id": "ea1598d8-1578-4ce3-8898-c47981e00e2a",
+													"temperature": 0.7
+												}
+											},
+											"creationTime": "2026-05-12 17:04:41",
+											"creatorUserId": "7F8A2BFE-402D-4499-9BB8-2EF7FFC7B993",
+											"description": "快速问答-描述",
+											"id": "b6ce2c6a-5cf5-46ba-9f3a-c85ee8de20a9",
+											"isDeleted": false,
+											"is_builtin": false,
+											"mode": "quick-answer",
+											"name": "快速问答-智能体",
+											"type": "rag-qa",
+											"updateTime": "2026-05-12 17:04:41"
+										}
+									],
+									"isAuthorized": true
+								}
+							},
+							"headers": {}
+						}
+					},
+					"security": []
+				}
+			}
+		},
 		"/api/ai/agent/pageList": {
 			"post": {
 				"summary": "获取分页列表",

+ 632 - 0
packages/api-service/schema/knowledge.openapi.json

@@ -542,6 +542,419 @@
 				"security": []
 			}
 		},
+		"/api/ai/knowledge-base/selectList": {
+			"post": {
+				"summary": "获取知识库选择列表",
+				"deprecated": false,
+				"description": "",
+				"tags": ["knowledge"],
+				"parameters": [
+					{
+						"name": "Authorization",
+						"in": "header",
+						"description": "",
+						"example": "bpm_client_1511371470951944192",
+						"schema": {
+							"type": "string",
+							"default": "bpm_client_1511371470951944192"
+						}
+					}
+				],
+				"requestBody": {
+					"content": {
+						"application/json": {
+							"schema": {
+								"type": "object",
+								"properties": {
+									"keyword": {
+										"type": "string"
+									},
+									"type": {
+										"type": "string"
+									}
+								},
+								"required": []
+							},
+							"example": {
+								"keyword": "",
+								"type": ""
+							}
+						}
+					},
+					"required": true
+				},
+				"responses": {
+					"200": {
+						"description": "",
+						"content": {
+							"application/json": {
+								"schema": {
+									"type": "object",
+									"properties": {
+										"isSuccess": {
+											"type": "boolean"
+										},
+										"code": {
+											"type": "integer"
+										},
+										"result": {
+											"type": "array",
+											"items": {
+												"type": "object",
+												"properties": {
+													"asr_config": {
+														"type": "object",
+														"properties": {
+															"enabled": {
+																"type": "boolean"
+															},
+															"language": {
+																"type": "string"
+															},
+															"model_id": {
+																"type": "string"
+															}
+														},
+														"required": ["enabled", "language", "model_id"]
+													},
+													"chunking_config": {
+														"type": "object",
+														"properties": {
+															"child_chunk_size": {
+																"type": "integer"
+															},
+															"chunk_overlap": {
+																"type": "integer"
+															},
+															"chunk_size": {
+																"type": "integer"
+															},
+															"enable_parent_child": {
+																"type": "boolean"
+															},
+															"parent_chunk_size": {
+																"type": "integer"
+															},
+															"parser_engine_rules": {
+																"type": "array",
+																"items": {
+																	"type": "object",
+																	"properties": {
+																		"engine": {
+																			"type": "string"
+																		},
+																		"file_types": {
+																			"type": "array",
+																			"items": {
+																				"type": "string"
+																			}
+																		}
+																	},
+																	"required": ["engine", "file_types"]
+																}
+															},
+															"separators": {
+																"type": "array",
+																"items": {
+																	"type": "string"
+																}
+															}
+														},
+														"required": [
+															"child_chunk_size",
+															"chunk_overlap",
+															"chunk_size",
+															"enable_parent_child",
+															"parent_chunk_size",
+															"parser_engine_rules",
+															"separators"
+														]
+													},
+													"creationTime": {
+														"type": "string"
+													},
+													"creatorUserId": {
+														"type": "string"
+													},
+													"description": {
+														"type": "string"
+													},
+													"embedding_model_id": {
+														"type": "string"
+													},
+													"faq_config": {
+														"type": "object",
+														"properties": {
+															"index_mode": {
+																"type": "string"
+															},
+															"question_index_mode": {
+																"type": "string"
+															}
+														},
+														"required": ["index_mode", "question_index_mode"]
+													},
+													"id": {
+														"type": "string"
+													},
+													"indexing_strategy": {
+														"type": "object",
+														"properties": {
+															"graph_enabled": {
+																"type": "boolean"
+															},
+															"keyword_enabled": {
+																"type": "boolean"
+															},
+															"vector_enabled": {
+																"type": "boolean"
+															},
+															"wiki_enabled": {
+																"type": "boolean"
+															}
+														},
+														"required": [
+															"graph_enabled",
+															"keyword_enabled",
+															"vector_enabled",
+															"wiki_enabled"
+														]
+													},
+													"isDeleted": {
+														"type": "boolean"
+													},
+													"is_pinned": {
+														"type": "boolean"
+													},
+													"is_temporary": {
+														"type": "boolean"
+													},
+													"name": {
+														"type": "string"
+													},
+													"question_generation_config": {
+														"type": "object",
+														"properties": {
+															"enabled": {
+																"type": "boolean"
+															},
+															"question_count": {
+																"type": "integer"
+															}
+														},
+														"required": ["enabled", "question_count"]
+													},
+													"storage_config": {
+														"type": "object",
+														"properties": {
+															"provider": {
+																"type": "string"
+															}
+														},
+														"required": ["provider"]
+													},
+													"storage_provider_config": {
+														"type": "object",
+														"properties": {
+															"provider": {
+																"type": "string"
+															}
+														},
+														"required": ["provider"]
+													},
+													"summary_model_id": {
+														"type": "string"
+													},
+													"type": {
+														"type": "string"
+													},
+													"updateTime": {
+														"type": "string"
+													},
+													"vlm_config": {
+														"type": "object",
+														"properties": {
+															"enabled": {
+																"type": "boolean"
+															},
+															"model_id": {
+																"type": "string"
+															}
+														},
+														"required": ["enabled", "model_id"]
+													},
+													"wiki_config": {
+														"type": "object",
+														"properties": {
+															"extraction_granularity": {
+																"type": "string"
+															},
+															"max_pages_per_ingest": {
+																"type": "integer"
+															},
+															"synthesis_model_id": {
+																"type": "string"
+															}
+														},
+														"required": [
+															"extraction_granularity",
+															"max_pages_per_ingest",
+															"synthesis_model_id"
+														]
+													},
+													"extract_config": {
+														"type": "object",
+														"properties": {
+															"enabled": {
+																"type": "boolean"
+															}
+														},
+														"required": ["enabled"]
+													}
+												},
+												"required": [
+													"asr_config",
+													"chunking_config",
+													"creationTime",
+													"creatorUserId",
+													"description",
+													"embedding_model_id",
+													"id",
+													"indexing_strategy",
+													"isDeleted",
+													"is_pinned",
+													"is_temporary",
+													"name",
+													"question_generation_config",
+													"storage_config",
+													"storage_provider_config",
+													"summary_model_id",
+													"type",
+													"updateTime",
+													"vlm_config",
+													"wiki_config"
+												]
+											}
+										},
+										"isAuthorized": {
+											"type": "boolean"
+										}
+									},
+									"required": ["isSuccess", "code", "result", "isAuthorized"]
+								},
+								"example": {
+									"isSuccess": true,
+									"code": 1,
+									"result": [
+										{
+											"asr_config": {
+												"enabled": false,
+												"language": "",
+												"model_id": ""
+											},
+											"chunking_config": {
+												"child_chunk_size": 384,
+												"chunk_overlap": 100,
+												"chunk_size": 512,
+												"enable_parent_child": true,
+												"parent_chunk_size": 4096,
+												"parser_engine_rules": [
+													{
+														"engine": "builtin",
+														"file_types": ["pdf"]
+													},
+													{
+														"engine": "builtin",
+														"file_types": ["docx", "doc"]
+													},
+													{
+														"engine": "markitdown",
+														"file_types": ["pptx", "ppt"]
+													},
+													{
+														"engine": "builtin",
+														"file_types": ["xlsx", "xls"]
+													},
+													{
+														"engine": "simple",
+														"file_types": ["csv"]
+													},
+													{
+														"engine": "builtin",
+														"file_types": ["md", "markdown"]
+													},
+													{
+														"engine": "simple",
+														"file_types": ["txt"]
+													},
+													{
+														"engine": "simple",
+														"file_types": ["json"]
+													},
+													{
+														"engine": "builtin",
+														"file_types": ["jpg", "jpeg", "png", "gif", "bmp", "tiff", "webp"]
+													},
+													{
+														"engine": "simple",
+														"file_types": ["mp3", "wav", "m4a", "flac", "ogg"]
+													}
+												],
+												"separators": ["\n\n", "\n", "。", "!", "?", ";", ";", " "]
+											},
+											"creationTime": "2026-05-10 22:01:13",
+											"creatorUserId": "7F8A2BFE-402D-4499-9BB8-2EF7FFC7B993",
+											"description": "FAQ描述",
+											"embedding_model_id": "569ae4d9-4af2-46f4-b8cc-4676044c7369",
+											"faq_config": {
+												"index_mode": "question_only",
+												"question_index_mode": "separate"
+											},
+											"id": "6039fdbe-5c47-46b3-a564-d57bf0c77289",
+											"indexing_strategy": {
+												"graph_enabled": false,
+												"keyword_enabled": true,
+												"vector_enabled": true,
+												"wiki_enabled": true
+											},
+											"isDeleted": false,
+											"is_pinned": false,
+											"is_temporary": false,
+											"name": "新的FAQ知识库",
+											"question_generation_config": {
+												"enabled": true,
+												"question_count": 3
+											},
+											"storage_config": {
+												"provider": "local"
+											},
+											"storage_provider_config": {
+												"provider": "local"
+											},
+											"summary_model_id": "ea1598d8-1578-4ce3-8898-c47981e00e2a",
+											"type": "faq",
+											"updateTime": "2026-05-10 22:01:13",
+											"vlm_config": {
+												"enabled": false,
+												"model_id": ""
+											},
+											"wiki_config": {
+												"extraction_granularity": "standard",
+												"max_pages_per_ingest": 0,
+												"synthesis_model_id": ""
+											}
+										}
+									],
+									"isAuthorized": true
+								}
+							},
+							"headers": {}
+						}
+					},
+					"security": []
+				}
+			}
+		},
 		"/api/ai/knowledge-base/pageList": {
 			"post": {
 				"summary": "获取知识库分页列表",
@@ -3423,6 +3836,225 @@
 				"security": []
 			}
 		},
+		"/api/ai/knowledge/selectList": {
+			"post": {
+				"summary": "获取知识选择列表",
+				"deprecated": false,
+				"description": "",
+				"tags": ["knowledge"],
+				"parameters": [
+					{
+						"name": "Authorization",
+						"in": "header",
+						"description": "",
+						"example": "bpm_client_1511371470951944192",
+						"schema": {
+							"type": "string",
+							"default": "bpm_client_1511371470951944192"
+						}
+					}
+				],
+				"requestBody": {
+					"content": {
+						"application/json": {
+							"schema": {
+								"type": "object",
+								"properties": {
+									"knowledge_base_id": {
+										"type": "string"
+									},
+									"title": {
+										"type": "string"
+									}
+								},
+								"required": ["knowledge_base_id"]
+							},
+							"example": {
+								"knowledge_base_id": "8d7ebada-8015-4d95-afba-8894c20024f1",
+								"title": ""
+							}
+						}
+					},
+					"required": true
+				},
+				"responses": {
+					"200": {
+						"description": "",
+						"content": {
+							"application/json": {
+								"schema": {
+									"type": "object",
+									"properties": {
+										"isSuccess": {
+											"type": "boolean"
+										},
+										"code": {
+											"type": "integer"
+										},
+										"result": {
+											"type": "object",
+											"properties": {
+												"currentPage": {
+													"type": "integer"
+												},
+												"hasNextPage": {
+													"type": "boolean"
+												},
+												"hasPreviousPage": {
+													"type": "boolean"
+												},
+												"model": {
+													"type": "array",
+													"items": {
+														"type": "object",
+														"properties": {
+															"channel": {
+																"type": "string"
+															},
+															"creationTime": {
+																"type": "string"
+															},
+															"description": {
+																"type": "string"
+															},
+															"embedding_model_id": {
+																"type": "string"
+															},
+															"enable_status": {
+																"type": "string"
+															},
+															"error_message": {
+																"type": "string"
+															},
+															"file_hash": {
+																"type": "string"
+															},
+															"file_name": {
+																"type": "string"
+															},
+															"file_path": {
+																"type": "string"
+															},
+															"file_size": {
+																"type": "integer"
+															},
+															"file_type": {
+																"type": "string"
+															},
+															"id": {
+																"type": "string"
+															},
+															"isDeleted": {
+																"type": "boolean"
+															},
+															"knowledge_base_id": {
+																"type": "string"
+															},
+															"metadata": {
+																"type": "object",
+																"properties": {}
+															},
+															"parse_status": {
+																"type": "string"
+															},
+															"source": {
+																"type": "string"
+															},
+															"storage_size": {
+																"type": "integer"
+															},
+															"summary_status": {
+																"type": "string"
+															},
+															"tag_id": {
+																"type": "string"
+															},
+															"title": {
+																"type": "string"
+															},
+															"type": {
+																"type": "string"
+															},
+															"updateTime": {
+																"type": "string"
+															}
+														}
+													}
+												},
+												"pageSize": {
+													"type": "integer"
+												},
+												"totalCount": {
+													"type": "integer"
+												},
+												"totalPages": {
+													"type": "integer"
+												}
+											},
+											"required": [
+												"currentPage",
+												"hasNextPage",
+												"hasPreviousPage",
+												"model",
+												"pageSize",
+												"totalCount",
+												"totalPages"
+											]
+										},
+										"isAuthorized": {
+											"type": "boolean"
+										}
+									},
+									"required": ["isSuccess", "code", "result", "isAuthorized"]
+								},
+								"example": {
+									"isSuccess": true,
+									"code": 1,
+									"result": {
+										"currentPage": 1,
+										"hasNextPage": true,
+										"hasPreviousPage": false,
+										"model": [
+											{
+												"channel": "web",
+												"creationTime": "2026-05-11 12:20:57",
+												"description": "",
+												"embedding_model_id": "569ae4d9-4af2-46f4-b8cc-4676044c7369",
+												"enable_status": "enabled",
+												"error_message": "",
+												"file_hash": "4764e6de0ee79fdfd02d8e9f24eebc0c",
+												"file_name": "Java代码.txt",
+												"file_path": "local://10000/9b7d1acb-606a-44d3-9311-2414c5a9aa52/1778473257185564121.txt",
+												"file_size": 9101,
+												"file_type": "txt",
+												"id": "9b7d1acb-606a-44d3-9311-2414c5a9aa52",
+												"isDeleted": false,
+												"knowledge_base_id": "8d7ebada-8015-4d95-afba-8894c20024f1",
+												"metadata": {},
+												"parse_status": "completed",
+												"source": "",
+												"storage_size": 170022,
+												"summary_status": "completed",
+												"tag_id": "",
+												"title": "Java代码.txt",
+												"type": "file",
+												"updateTime": "2026-05-11 12:20:57"
+											}
+										],
+										"pageSize": 20,
+										"totalCount": 1,
+										"totalPages": 1
+									},
+									"isAuthorized": true
+								}
+							}
+						},
+						"headers": {}
+					}
+				},
+				"security": []
+			}
+		},
 		"/api/ai/knowledge/pageList": {
 			"post": {
 				"summary": "获取知识分页列表",

+ 177 - 1
packages/api-service/schema/model.openapi.json

@@ -392,6 +392,181 @@
 				"security": []
 			}
 		},
+		"/api/ai/model/selectList": {
+			"post": {
+				"summary": "获取模型选择列表",
+				"deprecated": false,
+				"description": "",
+				"tags": ["ai-model"],
+				"parameters": [
+					{
+						"name": "Authorization",
+						"in": "header",
+						"description": "",
+						"example": "bpm_client_1500870842102321152",
+						"schema": {
+							"type": "string",
+							"default": "bpm_client_1500870842102321152"
+						}
+					}
+				],
+				"requestBody": {
+					"content": {
+						"application/json": {
+							"schema": {
+								"type": "object",
+								"properties": {
+									"keyword": {
+										"type": "string"
+									},
+									"type": {
+										"type": "string"
+									}
+								},
+								"required": []
+							},
+							"example": {
+								"keyword": "",
+								"type": "",
+								"source": ""
+							}
+						}
+					},
+					"required": true
+				},
+				"responses": {
+					"200": {
+						"description": "",
+						"content": {
+							"application/json": {
+								"schema": {
+									"type": "object",
+									"properties": {
+										"isSuccess": {
+											"type": "boolean"
+										},
+										"code": {
+											"type": "integer"
+										},
+										"result": {
+											"type": "array",
+											"items": {
+												"type": "object",
+												"properties": {
+													"creationTime": {
+														"type": "string"
+													},
+													"creatorUserId": {
+														"type": "string"
+													},
+													"description": {
+														"type": "string"
+													},
+													"id": {
+														"type": "string"
+													},
+													"isDeleted": {
+														"type": "boolean"
+													},
+													"is_default": {
+														"type": "boolean"
+													},
+													"name": {
+														"type": "string"
+													},
+													"parameters": {
+														"type": "object",
+														"properties": {
+															"api_key": {
+																"type": "string"
+															},
+															"base_url": {
+																"type": "string"
+															},
+															"embedding_parameters": {
+																"type": "object",
+																"properties": {
+																	"dimension": {
+																		"type": "integer"
+																	},
+																	"truncate_prompt_tokens": {
+																		"type": "integer"
+																	}
+																},
+																"required": ["dimension", "truncate_prompt_tokens"]
+															},
+															"provider": {
+																"type": "string"
+															}
+														},
+														"required": ["api_key", "base_url", "embedding_parameters", "provider"]
+													},
+													"provider": {
+														"type": "string"
+													},
+													"source": {
+														"type": "string"
+													},
+													"status": {
+														"type": "string"
+													},
+													"title": {
+														"type": "string"
+													},
+													"type": {
+														"type": "string"
+													},
+													"updateTime": {
+														"type": "string"
+													}
+												}
+											}
+										},
+										"isAuthorized": {
+											"type": "boolean"
+										}
+									},
+									"required": ["isSuccess", "code", "result", "isAuthorized"]
+								},
+								"example": {
+									"isSuccess": true,
+									"code": 1,
+									"result": [
+										{
+											"creationTime": "2026-05-10 10:53:15",
+											"creatorUserId": "7F8A2BFE-402D-4499-9BB8-2EF7FFC7B993",
+											"description": "火山引擎 Volcengine-vllm",
+											"id": "20ce3d44-0f68-45e5-b30c-06df4b402ec2",
+											"isDeleted": false,
+											"is_default": false,
+											"name": "ep-20260415150834-6bp4p",
+											"parameters": {
+												"api_key": "45991062-123b-48a7-9764-e3dc7db9b989",
+												"base_url": "https://ark.cn-beijing.volces.com/api/v3",
+												"embedding_parameters": {
+													"dimension": 0,
+													"truncate_prompt_tokens": 0
+												},
+												"provider": "volcengine"
+											},
+											"provider": "volcengine",
+											"source": "remote",
+											"status": "active",
+											"title": "火山引擎 Volcengine-vllm",
+											"type": "VLLM",
+											"updateTime": "2026-05-10 10:53:15"
+										}
+									],
+									"isAuthorized": true
+								}
+							},
+							"headers": {}
+						}
+					},
+					"security": []
+				}
+			}
+		},
 		"/api/ai/model/pageList": {
 			"post": {
 				"summary": "获取模型分页列表",
@@ -526,7 +701,8 @@
 																	"api_key",
 																	"base_url",
 																	"embedding_parameters",
-																	"provider"
+																	"provider",
+																	"id"
 																]
 															},
 															"provider": {

+ 335 - 0
packages/api-service/schema/resource.openapi.json

@@ -2408,6 +2408,125 @@
 				"security": []
 			}
 		},
+		"/api/ai/web-search/selectList": {
+			"post": {
+				"summary": "获取web搜索选择列表",
+				"deprecated": false,
+				"description": "",
+				"tags": ["resource"],
+				"parameters": [
+					{
+						"name": "Authorization",
+						"in": "header",
+						"description": "",
+						"example": "bpm_client_1513029045627916288",
+						"schema": {
+							"type": "string",
+							"default": "bpm_client_1513029045627916288"
+						}
+					}
+				],
+				"requestBody": {
+					"content": {
+						"application/json": {
+							"schema": {
+								"type": "object",
+								"properties": {
+									"keyword": {
+										"type": "string"
+									}
+								},
+								"required": []
+							},
+							"example": {
+								"keyword": "",
+								"provider": "",
+								"pageIndex": 1
+							}
+						}
+					},
+					"required": true
+				},
+				"responses": {
+					"200": {
+						"description": "",
+						"content": {
+							"application/json": {
+								"schema": {
+									"type": "object",
+									"properties": {
+										"isSuccess": {
+											"type": "boolean"
+										},
+										"code": {
+											"type": "integer"
+										},
+										"result": {
+											"type": "object",
+											"properties": {
+												"currentPage": {
+													"type": "integer"
+												},
+												"hasNextPage": {
+													"type": "boolean"
+												},
+												"hasPreviousPage": {
+													"type": "boolean"
+												},
+												"model": {
+													"type": "array",
+													"items": {
+														"type": "string"
+													}
+												},
+												"pageSize": {
+													"type": "integer"
+												},
+												"totalCount": {
+													"type": "integer"
+												},
+												"totalPages": {
+													"type": "integer"
+												}
+											},
+											"required": [
+												"currentPage",
+												"hasNextPage",
+												"hasPreviousPage",
+												"model",
+												"pageSize",
+												"totalCount",
+												"totalPages"
+											]
+										},
+										"isAuthorized": {
+											"type": "boolean"
+										}
+									},
+									"required": ["isSuccess", "code", "result", "isAuthorized"]
+								},
+								"example": {
+									"isSuccess": true,
+									"code": 1,
+									"result": {
+										"currentPage": 1,
+										"hasNextPage": false,
+										"hasPreviousPage": false,
+										"model": [],
+										"pageSize": 20,
+										"totalCount": 0,
+										"totalPages": 0
+									},
+									"isAuthorized": true
+								}
+							}
+						},
+						"headers": {}
+					}
+				},
+				"security": []
+			}
+		},
 		"/api/ai/web-search/info": {
 			"post": {
 				"summary": "获取详情",
@@ -3390,6 +3509,222 @@
 				"security": []
 			}
 		},
+		"/api/ai/mcp/selectList": {
+			"post": {
+				"summary": "获取mcp选择列表",
+				"deprecated": false,
+				"description": "",
+				"tags": ["resource"],
+				"parameters": [
+					{
+						"name": "Authorization",
+						"in": "header",
+						"description": "",
+						"example": "bpm_client_1513029045627916288",
+						"schema": {
+							"type": "string",
+							"default": "bpm_client_1513029045627916288"
+						}
+					}
+				],
+				"requestBody": {
+					"content": {
+						"application/json": {
+							"schema": {
+								"type": "object",
+								"properties": {
+									"keyword": {
+										"type": "string"
+									}
+								},
+								"required": []
+							},
+							"example": {
+								"keyword": "",
+								"transport_type": "",
+								"pageIndex": 1,
+								"pageSize": 20
+							}
+						}
+					},
+					"required": true
+				},
+				"responses": {
+					"200": {
+						"description": "",
+						"content": {
+							"application/json": {
+								"schema": {
+									"type": "object",
+									"properties": {
+										"isSuccess": {
+											"type": "boolean"
+										},
+										"code": {
+											"type": "integer"
+										},
+										"result": {
+											"type": "object",
+											"properties": {
+												"currentPage": {
+													"type": "integer"
+												},
+												"hasNextPage": {
+													"type": "boolean"
+												},
+												"hasPreviousPage": {
+													"type": "boolean"
+												},
+												"model": {
+													"type": "array",
+													"items": {
+														"type": "object",
+														"properties": {
+															"advanced_config": {
+																"type": "object",
+																"properties": {
+																	"retry_count": {
+																		"type": "integer"
+																	},
+																	"retry_delay": {
+																		"type": "integer"
+																	},
+																	"timeout": {
+																		"type": "integer"
+																	}
+																},
+																"required": ["retry_count", "retry_delay", "timeout"]
+															},
+															"auth_config": {
+																"type": "object",
+																"properties": {}
+															},
+															"creationTime": {
+																"type": "string"
+															},
+															"creatorUserId": {
+																"type": "string"
+															},
+															"description": {
+																"type": "string"
+															},
+															"enabled": {
+																"type": "boolean"
+															},
+															"env_vars": {
+																"type": "object",
+																"properties": {}
+															},
+															"headers": {
+																"type": "object",
+																"properties": {}
+															},
+															"id": {
+																"type": "string"
+															},
+															"isDeleted": {
+																"type": "boolean"
+															},
+															"is_builtin": {
+																"type": "boolean"
+															},
+															"name": {
+																"type": "string"
+															},
+															"stdio_config": {
+																"type": "object",
+																"properties": {
+																	"command": {
+																		"type": "string"
+																	}
+																},
+																"required": ["command"]
+															},
+															"transport_type": {
+																"type": "string"
+															},
+															"updateTime": {
+																"type": "string"
+															},
+															"url": {
+																"type": "string"
+															}
+														}
+													}
+												},
+												"pageSize": {
+													"type": "integer"
+												},
+												"totalCount": {
+													"type": "integer"
+												},
+												"totalPages": {
+													"type": "integer"
+												}
+											},
+											"required": [
+												"currentPage",
+												"hasNextPage",
+												"hasPreviousPage",
+												"model",
+												"pageSize",
+												"totalCount",
+												"totalPages"
+											]
+										},
+										"isAuthorized": {
+											"type": "boolean"
+										}
+									},
+									"required": ["isSuccess", "code", "result", "isAuthorized"]
+								},
+								"example": {
+									"isSuccess": true,
+									"code": 1,
+									"result": {
+										"currentPage": 1,
+										"hasNextPage": true,
+										"hasPreviousPage": false,
+										"model": [
+											{
+												"advanced_config": {
+													"retry_count": 3,
+													"retry_delay": 1,
+													"timeout": 30
+												},
+												"auth_config": {},
+												"creationTime": "2026-05-15 16:51:27",
+												"creatorUserId": "7F8A2BFE-402D-4499-9BB8-2EF7FFC7B993",
+												"description": "沙鲁的MCP服务",
+												"enabled": false,
+												"env_vars": {},
+												"headers": {},
+												"id": "da3f6fb2-171b-434a-976f-be2260b3f0dc",
+												"isDeleted": false,
+												"is_builtin": false,
+												"name": "新的MCP",
+												"stdio_config": {
+													"command": ""
+												},
+												"transport_type": "http-streamable",
+												"updateTime": "2026-05-15 16:51:27",
+												"url": "http://shalu-componenttesting-c-dev.shalu.com/api/mcp/account"
+											}
+										],
+										"pageSize": 20,
+										"totalCount": 1,
+										"totalPages": 1
+									},
+									"isAuthorized": true
+								}
+							}
+						},
+						"headers": {}
+					}
+				},
+				"security": []
+			}
+		},
 		"/api/ai/mcp/info": {
 			"post": {
 				"summary": "获取详情",

+ 237 - 0
packages/api-service/schema/vector.openapi.json

@@ -722,6 +722,243 @@
 				"security": []
 			}
 		},
+		"/api/ai/vector-store/selectList": {
+			"post": {
+				"summary": "获取向量选择列表",
+				"deprecated": false,
+				"description": "",
+				"tags": ["vector"],
+				"parameters": [
+					{
+						"name": "Authorization",
+						"in": "header",
+						"description": "",
+						"example": "bpm_client_1520995593147650048",
+						"schema": {
+							"type": "string"
+						}
+					}
+				],
+				"requestBody": {
+					"content": {
+						"application/json": {
+							"schema": {
+								"type": "object",
+								"properties": {
+									"keyword": {
+										"type": "string"
+									}
+								},
+								"required": []
+							},
+							"example": {
+								"keyword": ""
+							}
+						}
+					},
+					"required": true
+				},
+				"responses": {
+					"200": {
+						"description": "",
+						"content": {
+							"application/json": {
+								"schema": {
+									"type": "object",
+									"properties": {
+										"isSuccess": {
+											"type": "boolean"
+										},
+										"code": {
+											"type": "integer"
+										},
+										"result": {
+											"type": "array",
+											"items": {
+												"type": "object",
+												"properties": {
+													"connection_fields": {
+														"type": "array",
+														"items": {
+															"type": "object",
+															"properties": {
+																"default": {
+																	"type": "string"
+																},
+																"description": {
+																	"type": "string"
+																},
+																"immutable": {
+																	"type": "boolean"
+																},
+																"name": {
+																	"type": "string"
+																},
+																"required": {
+																	"type": "boolean"
+																},
+																"sensitive": {
+																	"type": "boolean"
+																},
+																"type": {
+																	"type": "string"
+																}
+															},
+															"required": [
+																"default",
+																"description",
+																"immutable",
+																"name",
+																"required",
+																"sensitive",
+																"type"
+															]
+														}
+													},
+													"display_name": {
+														"type": "string"
+													},
+													"index_fields": {
+														"type": "array",
+														"items": {
+															"type": "object",
+															"properties": {
+																"default": {
+																	"type": "string"
+																},
+																"description": {
+																	"type": "string"
+																},
+																"immutable": {
+																	"type": "boolean"
+																},
+																"name": {
+																	"type": "string"
+																},
+																"required": {
+																	"type": "boolean"
+																},
+																"sensitive": {
+																	"type": "boolean"
+																},
+																"type": {
+																	"type": "string"
+																},
+																"max": {
+																	"type": "integer"
+																},
+																"min": {
+																	"type": "integer"
+																},
+																"enum": {
+																	"type": "array",
+																	"items": {
+																		"type": "string"
+																	}
+																}
+															},
+															"required": [
+																"default",
+																"description",
+																"immutable",
+																"name",
+																"required",
+																"sensitive",
+																"type",
+																"max",
+																"min"
+															]
+														}
+													},
+													"type": {
+														"type": "string"
+													}
+												},
+												"required": ["connection_fields", "display_name", "index_fields", "type"]
+											}
+										},
+										"isAuthorized": {
+											"type": "boolean"
+										}
+									},
+									"required": ["isSuccess", "code", "result", "isAuthorized"]
+								},
+								"example": {
+									"isSuccess": true,
+									"code": 1,
+									"result": [
+										{
+											"connection_fields": [
+												{
+													"default": "http://localhost:9200",
+													"description": "URL",
+													"immutable": false,
+													"name": "addr",
+													"required": true,
+													"sensitive": false,
+													"type": "string"
+												},
+												{
+													"default": "elastic",
+													"description": "Username",
+													"immutable": false,
+													"name": "username",
+													"required": false,
+													"sensitive": false,
+													"type": "string"
+												},
+												{
+													"description": "Password",
+													"immutable": false,
+													"name": "password",
+													"required": false,
+													"sensitive": true,
+													"type": "string"
+												}
+											],
+											"display_name": "Elasticsearch",
+											"index_fields": [
+												{
+													"default": "weknora",
+													"description": "Index Name",
+													"immutable": false,
+													"name": "index_name",
+													"required": false,
+													"sensitive": false,
+													"type": "string"
+												},
+												{
+													"default": "4",
+													"description": "Shards",
+													"immutable": false,
+													"name": "number_of_shards",
+													"required": false,
+													"sensitive": false,
+													"type": "number"
+												},
+												{
+													"default": "1",
+													"description": "Replicas",
+													"immutable": false,
+													"name": "number_of_replicas",
+													"required": false,
+													"sensitive": false,
+													"type": "number"
+												}
+											],
+											"type": "elasticsearch"
+										}
+									],
+									"isAuthorized": true
+								}
+							},
+							"headers": {}
+						}
+					},
+					"security": []
+				}
+			}
+		},
 		"/api/ai/vector-store/pageList": {
 			"post": {
 				"summary": "获取分页列表",

+ 55 - 0
packages/api-service/servers/api/agentApplication.ts

@@ -319,6 +319,61 @@ export async function postAiAgentPageList(
   })
 }
 
+/** 获取智能体选择列表 POST /api/ai/agent/selectList */
+export async function postAiAgentSelectList(
+  body: {
+    keyword?: string
+    mode?: string
+    type?: string
+  },
+  options?: { [key: string]: any }
+) {
+  return request<{
+    isSuccess: boolean
+    code: number
+    result: {
+      avatar?: string
+      config: {
+        advanced_config: {
+          enable_query_expansion: boolean
+          enable_rewrite: boolean
+          fallback_prompt: string
+          fallback_response: string
+          fallback_strategy: string
+          rewrite_prompt_system: string
+          rewrite_prompt_user: string
+        }
+        basic_config: {
+          agent_mode: string
+          agent_type: string
+          context_template: string
+          suggested_prompts: string[]
+          system_prompt: string
+        }
+        model_config: { max_completion_tokens: number; model_id: string; temperature: number }
+      }
+      creationTime?: string
+      creatorUserId?: string
+      description?: string
+      id?: string
+      isDeleted?: boolean
+      is_builtin?: boolean
+      mode?: string
+      name?: string
+      type?: string
+      updateTime?: string
+    }[]
+    isAuthorized: boolean
+  }>('/api/ai/agent/selectList', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    data: body,
+    ...(options || {})
+  })
+}
+
 /** 获取智能体建议提问列表 POST /api/ai/agent/suggested-questions */
 export async function postAiAgentSuggestedQuestions(
   body: {

+ 118 - 0
packages/api-service/servers/knowledge/api/knowledge.ts

@@ -498,6 +498,69 @@ export async function postAiKnowledgeBasePageList(
   })
 }
 
+/** 获取知识库选择列表 POST /api/ai/knowledge-base/selectList */
+export async function postAiKnowledgeBaseSelectList(
+  body: {
+    keyword?: string
+    type?: string
+  },
+  options?: { [key: string]: any }
+) {
+  return request<{
+    isSuccess: boolean
+    code: number
+    result: {
+      asr_config: { enabled: boolean; language: string; model_id: string }
+      chunking_config: {
+        child_chunk_size: number
+        chunk_overlap: number
+        chunk_size: number
+        enable_parent_child: boolean
+        parent_chunk_size: number
+        parser_engine_rules: { engine: string; file_types: string[] }[]
+        separators: string[]
+      }
+      creationTime: string
+      creatorUserId: string
+      description: string
+      embedding_model_id: string
+      faq_config: { index_mode: string; question_index_mode: string }
+      id: string
+      indexing_strategy: {
+        graph_enabled: boolean
+        keyword_enabled: boolean
+        vector_enabled: boolean
+        wiki_enabled: boolean
+      }
+      isDeleted: boolean
+      is_pinned: boolean
+      is_temporary: boolean
+      name: string
+      question_generation_config: { enabled: boolean; question_count: number }
+      storage_config: { provider: string }
+      storage_provider_config: { provider: string }
+      summary_model_id: string
+      type: string
+      updateTime: string
+      vlm_config: { enabled: boolean; model_id: string }
+      wiki_config: {
+        extraction_granularity: string
+        max_pages_per_ingest: number
+        synthesis_model_id: string
+      }
+      extract_config: { enabled: boolean }
+    }[]
+    isAuthorized: boolean
+  }>('/api/ai/knowledge-base/selectList', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    data: body,
+    ...(options || {})
+  })
+}
+
 /** 更新知识库 POST /api/ai/knowledge-base/update */
 export async function postAiKnowledgeBaseUpdate(
   body: {
@@ -744,6 +807,61 @@ export async function postAiKnowledgeReparse(
   )
 }
 
+/** 获取知识选择列表 POST /api/ai/knowledge/selectList */
+export async function postAiKnowledgeSelectList(
+  body: {
+    knowledge_base_id: string
+    title?: string
+  },
+  options?: { [key: string]: any }
+) {
+  return request<{
+    isSuccess: boolean
+    code: number
+    result: {
+      currentPage: number
+      hasNextPage: boolean
+      hasPreviousPage: boolean
+      model: {
+        channel?: string
+        creationTime?: string
+        description?: string
+        embedding_model_id?: string
+        enable_status?: string
+        error_message?: string
+        file_hash?: string
+        file_name?: string
+        file_path?: string
+        file_size?: number
+        file_type?: string
+        id?: string
+        isDeleted?: boolean
+        knowledge_base_id?: string
+        metadata?: Record<string, any>
+        parse_status?: string
+        source?: string
+        storage_size?: number
+        summary_status?: string
+        tag_id?: string
+        title?: string
+        type?: string
+        updateTime?: string
+      }[]
+      pageSize: number
+      totalCount: number
+      totalPages: number
+    }
+    isAuthorized: boolean
+  }>('/api/ai/knowledge/selectList', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    data: body,
+    ...(options || {})
+  })
+}
+
 /** 更新知识 POST /api/ai/knowledge/update */
 export async function postAiKnowledgeUpdate(
   body: {

+ 43 - 0
packages/api-service/servers/model/api/aiModel.ts

@@ -200,6 +200,49 @@ export async function postModelProviders(
   })
 }
 
+/** 获取模型选择列表 POST /api/ai/model/selectList */
+export async function postModelSelectList(
+  body: {
+    keyword?: string
+    type?: string
+  },
+  options?: { [key: string]: any }
+) {
+  return request<{
+    isSuccess: boolean
+    code: number
+    result: {
+      creationTime?: string
+      creatorUserId?: string
+      description?: string
+      id?: string
+      isDeleted?: boolean
+      is_default?: boolean
+      name?: string
+      parameters: {
+        api_key: string
+        base_url: string
+        embedding_parameters: { dimension: number; truncate_prompt_tokens: number }
+        provider: string
+      }
+      provider?: string
+      source?: string
+      status?: string
+      title?: string
+      type?: string
+      updateTime?: string
+    }[]
+    isAuthorized: boolean
+  }>('/api/ai/model/selectList', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    data: body,
+    ...(options || {})
+  })
+}
+
 /** 更新模型 POST /api/ai/model/update */
 export async function postModelUpdate(
   body: {

+ 77 - 0
packages/api-service/servers/resource/api/resource.ts

@@ -199,6 +199,53 @@ export async function postMcpResources(
   )
 }
 
+/** 获取mcp选择列表 POST /api/ai/mcp/selectList */
+export async function postMcpSelectList(
+  body: {
+    keyword?: string
+  },
+  options?: { [key: string]: any }
+) {
+  return request<{
+    isSuccess: boolean
+    code: number
+    result: {
+      currentPage: number
+      hasNextPage: boolean
+      hasPreviousPage: boolean
+      model: {
+        advanced_config: { retry_count: number; retry_delay: number; timeout: number }
+        auth_config?: Record<string, any>
+        creationTime?: string
+        creatorUserId?: string
+        description?: string
+        enabled?: boolean
+        env_vars?: Record<string, any>
+        headers?: Record<string, any>
+        id?: string
+        isDeleted?: boolean
+        is_builtin?: boolean
+        name?: string
+        stdio_config: { command: string }
+        transport_type?: string
+        updateTime?: string
+        url?: string
+      }[]
+      pageSize: number
+      totalCount: number
+      totalPages: number
+    }
+    isAuthorized: boolean
+  }>('/api/ai/mcp/selectList', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    data: body,
+    ...(options || {})
+  })
+}
+
 /** 获取MCP服务工具列表 POST /api/ai/mcp/tools */
 export async function postMcpTools(
   body: {
@@ -781,6 +828,36 @@ export async function postWebSearchPageList(
   })
 }
 
+/** 获取web搜索选择列表 POST /api/ai/web-search/selectList */
+export async function postWebSearchSelectList(
+  body: {
+    keyword?: string
+  },
+  options?: { [key: string]: any }
+) {
+  return request<{
+    isSuccess: boolean
+    code: number
+    result: {
+      currentPage: number
+      hasNextPage: boolean
+      hasPreviousPage: boolean
+      model: string[]
+      pageSize: number
+      totalCount: number
+      totalPages: number
+    }
+    isAuthorized: boolean
+  }>('/api/ai/web-search/selectList', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    data: body,
+    ...(options || {})
+  })
+}
+
 /** 更新网络搜索厂商 POST /api/ai/web-search/update */
 export async function postWebSearchUpdate(
   body: {

+ 46 - 0
packages/api-service/servers/vector/api/vector.ts

@@ -186,6 +186,52 @@ export async function postPageList(
   })
 }
 
+/** 获取向量选择列表 POST /api/ai/vector-store/selectList */
+export async function postSelectList(
+  body: {
+    keyword?: string
+  },
+  options?: { [key: string]: any }
+) {
+  return request<{
+    isSuccess: boolean
+    code: number
+    result: {
+      connection_fields: {
+        default: string
+        description: string
+        immutable: boolean
+        name: string
+        required: boolean
+        sensitive: boolean
+        type: string
+      }[]
+      display_name: string
+      index_fields: {
+        default: string
+        description: string
+        immutable: boolean
+        name: string
+        required: boolean
+        sensitive: boolean
+        type: string
+        max: number
+        min: number
+        enum?: string[]
+      }[]
+      type: string
+    }[]
+    isAuthorized: boolean
+  }>('/api/ai/vector-store/selectList', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    data: body,
+    ...(options || {})
+  })
+}
+
 /** 获取支持的向量存储类型列表 POST /api/ai/vector-store/types */
 export async function postTypes(body: {}, options?: { [key: string]: any }) {
   return request<{