diff --git a/backend/package/yuxi/knowledge/implementations/lightrag.py b/backend/package/yuxi/knowledge/implementations/lightrag.py
index cb8c9fd2..d0e22971 100644
--- a/backend/package/yuxi/knowledge/implementations/lightrag.py
+++ b/backend/package/yuxi/knowledge/implementations/lightrag.py
@@ -302,7 +302,9 @@ class LightRagKB(KnowledgeBase):
),
)
- async def index_file(self, db_id: str, file_id: str, operator_id: str | None = None, params: dict | None = None) -> dict:
+ async def index_file(
+ self, db_id: str, file_id: str, operator_id: str | None = None, params: dict | None = None
+ ) -> dict:
"""
Index parsed file (Status: INDEXING -> INDEXED/ERROR_INDEXING)
@@ -395,7 +397,7 @@ class LightRagKB(KnowledgeBase):
logger.info(
f"Indexed file {file_id} into LightRAG with {len(chunks)} chunks, "
- f"chunk_preset_id={processing_params.get('chunk_preset_id')}"
+ f"chunk_preset_id={params.get('chunk_preset_id')}"
)
# Update status
diff --git a/backend/package/yuxi/knowledge/implementations/milvus.py b/backend/package/yuxi/knowledge/implementations/milvus.py
index 59579ea5..35b82a2d 100644
--- a/backend/package/yuxi/knowledge/implementations/milvus.py
+++ b/backend/package/yuxi/knowledge/implementations/milvus.py
@@ -284,7 +284,9 @@ class MilvusKB(KnowledgeBase):
"""将文本分割成块"""
return chunk_markdown(text, file_id, filename, params)
- async def index_file(self, db_id: str, file_id: str, operator_id: str | None = None, params: dict | None = None) -> dict:
+ async def index_file(
+ self, db_id: str, file_id: str, operator_id: str | None = None, params: dict | None = None
+ ) -> dict:
"""
Index parsed file (Status: INDEXING -> INDEXED/ERROR_INDEXING)
diff --git a/backend/package/yuxi/knowledge/manager.py b/backend/package/yuxi/knowledge/manager.py
index 77bdc54a..b23ed87d 100644
--- a/backend/package/yuxi/knowledge/manager.py
+++ b/backend/package/yuxi/knowledge/manager.py
@@ -415,7 +415,9 @@ class KnowledgeBaseManager:
kb_instance = await self._get_kb_for_database(db_id)
return await kb_instance.parse_file(db_id, file_id, operator_id)
- async def index_file(self, db_id: str, file_id: str, operator_id: str | None = None, params: dict | None = None) -> dict:
+ async def index_file(
+ self, db_id: str, file_id: str, operator_id: str | None = None, params: dict | None = None
+ ) -> dict:
"""Index parsed file"""
kb_instance = await self._get_kb_for_database(db_id)
return await kb_instance.index_file(db_id, file_id, operator_id, params=params)
diff --git a/backend/package/yuxi/services/chat_service.py b/backend/package/yuxi/services/chat_service.py
index 518d186e..b9cb9def 100644
--- a/backend/package/yuxi/services/chat_service.py
+++ b/backend/package/yuxi/services/chat_service.py
@@ -263,6 +263,7 @@ async def save_messages_from_langgraph_state(
elif msg_type == "tool":
await _save_tool_message(conv_repo, msg_dict)
+
def _extract_interrupt_info(state) -> Any | None:
"""从 LangGraph state 中提取中断信息"""
if hasattr(state, "tasks") and state.tasks:
@@ -1086,7 +1087,7 @@ async def stream_agent_resume(
except Exception as e:
logger.error(f"Error saving messages from LangGraph state: {e}")
logger.error(traceback.format_exc())
- yield make_chunk(status="warning", message=f"消息保存失败: {e}", meta=meta)
+ yield make_resume_chunk(status="warning", message=f"消息保存失败: {e}", meta=meta)
yield make_resume_chunk(status="finished", meta=meta)
diff --git a/backend/package/yuxi/services/model_provider_service.py b/backend/package/yuxi/services/model_provider_service.py
index f4125108..ec4b6d37 100644
--- a/backend/package/yuxi/services/model_provider_service.py
+++ b/backend/package/yuxi/services/model_provider_service.py
@@ -7,6 +7,7 @@ from typing import Any
import httpx
from sqlalchemy.ext.asyncio import AsyncSession
+from yuxi.config.builtin_providers import BUILTIN_PROVIDERS
from yuxi.repositories.model_provider_repository import (
create_model_provider,
delete_model_provider,
@@ -14,7 +15,6 @@ from yuxi.repositories.model_provider_repository import (
list_model_providers,
update_model_provider,
)
-from yuxi.config.builtin_providers import BUILTIN_PROVIDERS
from yuxi.services.model_cache import is_v2_spec_format
from yuxi.storage.postgres.models_business import ModelProvider
diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts
index 93cb262b..5c4edf65 100644
--- a/docs/.vitepress/config.mts
+++ b/docs/.vitepress/config.mts
@@ -11,7 +11,8 @@ export default defineConfig({
ignoreDeadLinks: [
/localhost/,
/CONTRIBUTING$/,
- /docker-compose\.yml$/
+ /docker-compose\.yml$/,
+ /^\.\/intro\//
],
markdown: {
config: (md) => {
diff --git a/web/src/assets/css/extension-detail.less b/web/src/assets/css/extension-detail.less
index e7550cf3..6747b411 100644
--- a/web/src/assets/css/extension-detail.less
+++ b/web/src/assets/css/extension-detail.less
@@ -27,7 +27,9 @@
cursor: pointer;
padding: 4px 8px;
border-radius: 6px;
- transition: color 0.15s, background 0.15s;
+ transition:
+ color 0.15s,
+ background 0.15s;
&:hover {
color: var(--gray-700);
@@ -90,4 +92,4 @@
min-height: 0;
overflow: hidden;
}
-}
\ No newline at end of file
+}
diff --git a/web/src/assets/css/model-selector-common.less b/web/src/assets/css/model-selector-common.less
index 52d0cfa1..34c2dead 100644
--- a/web/src/assets/css/model-selector-common.less
+++ b/web/src/assets/css/model-selector-common.less
@@ -86,7 +86,6 @@
}
}
-
// Provider 标签样式
.provider-tag {
padding: 2px 4px;
diff --git a/web/src/components/EmbeddingModelSelector.vue b/web/src/components/EmbeddingModelSelector.vue
index 6305ca1e..56dc18d1 100644
--- a/web/src/components/EmbeddingModelSelector.vue
+++ b/web/src/components/EmbeddingModelSelector.vue
@@ -101,7 +101,12 @@ const emit = defineEmits(['update:value', 'change'])
const v2Models = ref({})
const v1ModelStatuses = reactive({})
-const { statusMap: v2ModelStatuses, getStatusIcon: getV2StatusIcon, getStatusClass: getV2StatusClass, getStatusTooltip: getV2StatusTooltip, checkV2Status, checkV2Statuses } = useModelStatus()
+const {
+ getStatusIcon: getV2StatusIcon,
+ getStatusClass: getV2StatusClass,
+ getStatusTooltip: getV2StatusTooltip,
+ checkV2Statuses
+} = useModelStatus()
const state = reactive({
checkingStatus: false
})
diff --git a/web/src/components/KnowledgeBaseCard.vue b/web/src/components/KnowledgeBaseCard.vue
index 12478f98..015fd5f6 100644
--- a/web/src/components/KnowledgeBaseCard.vue
+++ b/web/src/components/KnowledgeBaseCard.vue
@@ -530,12 +530,33 @@ const deleteDatabase = () => {
background: var(--gray-100);
color: var(--gray-600);
- &.tag-purple { background: #f3e8ff; color: #7c3aed; }
- &.tag-blue { background: var(--color-info-50); color: var(--color-info-700); }
- &.tag-red { background: var(--color-error-50); color: var(--color-error-700); }
- &.tag-green { background: var(--color-success-50); color: var(--color-success-700); }
- &.tag-gold { background: #fef3c7; color: #d97706; }
- &.tag-cyan { background: #cffafe; color: #0891b2; }
- &.tag-orange { background: #fff7ed; color: #ea580c; }
+ &.tag-purple {
+ background: #f3e8ff;
+ color: #7c3aed;
+ }
+ &.tag-blue {
+ background: var(--color-info-50);
+ color: var(--color-info-700);
+ }
+ &.tag-red {
+ background: var(--color-error-50);
+ color: var(--color-error-700);
+ }
+ &.tag-green {
+ background: var(--color-success-50);
+ color: var(--color-success-700);
+ }
+ &.tag-gold {
+ background: #fef3c7;
+ color: #d97706;
+ }
+ &.tag-cyan {
+ background: #cffafe;
+ color: #0891b2;
+ }
+ &.tag-orange {
+ background: #fff7ed;
+ color: #ea580c;
+ }
}
diff --git a/web/src/components/ModelSelectorComponent.vue b/web/src/components/ModelSelectorComponent.vue
index 925381a9..a88b487f 100644
--- a/web/src/components/ModelSelectorComponent.vue
+++ b/web/src/components/ModelSelectorComponent.vue
@@ -125,7 +125,7 @@ const refreshCache = async () => {
}
// 状态管理
-const { statusMap: modelStatusMap, getStatusIcon, getStatusTooltip } = useModelStatus()
+useModelStatus()
const state = reactive({
currentModelStatus: null,
checkingStatus: false,
@@ -197,7 +197,6 @@ const handleSelectV2Model = (spec) => {
\ No newline at end of file
+
diff --git a/web/src/components/extensions/ExtensionToolbar.vue b/web/src/components/extensions/ExtensionToolbar.vue
index bf7d8070..dbee79ad 100644
--- a/web/src/components/extensions/ExtensionToolbar.vue
+++ b/web/src/components/extensions/ExtensionToolbar.vue
@@ -76,4 +76,4 @@ defineProps({
background-color: transparent;
}
}
-
\ No newline at end of file
+
diff --git a/web/src/components/extensions/McpCardList.vue b/web/src/components/extensions/McpCardList.vue
index d7a87391..eb907725 100644
--- a/web/src/components/extensions/McpCardList.vue
+++ b/web/src/components/extensions/McpCardList.vue
@@ -14,8 +14,14 @@
-
-
+
@@ -89,7 +95,10 @@ const formModalVisible = ref(false)
const filteredServers = computed(() => {
const sorted = [...servers.value].sort((a, b) =>
- String(a.name || '').localeCompare(String(b.name || ''), 'zh-Hans-CN', { sensitivity: 'base', numeric: true })
+ String(a.name || '').localeCompare(String(b.name || ''), 'zh-Hans-CN', {
+ sensitivity: 'base',
+ numeric: true
+ })
)
if (!searchQuery.value) return sorted
const q = searchQuery.value.toLowerCase()
@@ -98,8 +107,12 @@ const filteredServers = computed(() => {
)
})
-const filteredEnabledServers = computed(() => filteredServers.value.filter((item) => !!item.enabled))
-const filteredDisabledServers = computed(() => filteredServers.value.filter((item) => !item.enabled))
+const filteredEnabledServers = computed(() =>
+ filteredServers.value.filter((item) => !!item.enabled)
+)
+const filteredDisabledServers = computed(() =>
+ filteredServers.value.filter((item) => !item.enabled)
+)
const getTransportColor = (transport) => {
const colors = { sse: 'orange', stdio: 'green', streamable_http: 'blue' }
@@ -109,7 +122,8 @@ const getTransportColor = (transport) => {
const mcpTags = (server) => {
const tags = []
if (server.created_by === 'system') tags.push({ name: '内置' })
- if (server.transport) tags.push({ name: server.transport, color: getTransportColor(server.transport) })
+ if (server.transport)
+ tags.push({ name: server.transport, color: getTransportColor(server.transport) })
return tags
}
@@ -168,4 +182,4 @@ defineExpose({ fetchServers, loading })
font-size: 18px;
line-height: 1;
}
-
\ No newline at end of file
+
diff --git a/web/src/components/extensions/McpDetailView.vue b/web/src/components/extensions/McpDetailView.vue
index f1dfbc96..284d909e 100644
--- a/web/src/components/extensions/McpDetailView.vue
+++ b/web/src/components/extensions/McpDetailView.vue
@@ -40,7 +40,9 @@
:class="[
'lucide-icon-btn',
'extension-panel-action',
- server?.enabled === false ? 'extension-panel-action-primary' : 'extension-panel-action-danger'
+ server?.enabled === false
+ ? 'extension-panel-action-primary'
+ : 'extension-panel-action-danger'
]"
>
@@ -68,21 +70,31 @@
- {{ server.transport }}
+ {{
+ server.transport
+ }}
-
+
-
+
{{ server.url }}
-
+
{{ JSON.stringify(server.headers, null, 2) }}
@@ -103,7 +115,9 @@
- {{ arg }}
+ {{
+ arg
+ }}
@@ -184,7 +198,10 @@
{{ tool.description }}
-
+
-
{{ param.description }}
+
+ {{ param.description }}
+
@@ -272,7 +295,9 @@ const filteredTools = computed(() => {
if (!toolSearchText.value) return tools.value
const search = toolSearchText.value.toLowerCase()
return tools.value.filter(
- (t) => t.name.toLowerCase().includes(search) || (t.description && t.description.toLowerCase().includes(search))
+ (t) =>
+ t.name.toLowerCase().includes(search) ||
+ (t.description && t.description.toLowerCase().includes(search))
)
})
@@ -458,4 +483,4 @@ onMounted(() => {
padding: 16px var(--page-padding);
}
}
-
\ No newline at end of file
+
diff --git a/web/src/components/extensions/McpFormModal.vue b/web/src/components/extensions/McpFormModal.vue
index 3c1d7ea8..5206170d 100644
--- a/web/src/components/extensions/McpFormModal.vue
+++ b/web/src/components/extensions/McpFormModal.vue
@@ -18,7 +18,11 @@
-
+
@@ -44,17 +48,31 @@
-
+
-
+
-
+
@@ -64,14 +82,24 @@
-
+
-
+
@@ -79,7 +107,7 @@
@@ -129,7 +157,10 @@ const form = reactive({
})
const isStdioTransport = computed(
- () => String(form.transport || '').trim().toLowerCase() === 'stdio'
+ () =>
+ String(form.transport || '')
+ .trim()
+ .toLowerCase() === 'stdio'
)
watch(
@@ -310,4 +341,4 @@ const handleFormSubmit = async () => {
gap: 8px;
}
}
-
\ No newline at end of file
+
diff --git a/web/src/components/extensions/SkillCardList.vue b/web/src/components/extensions/SkillCardList.vue
index e5561764..36310351 100644
--- a/web/src/components/extensions/SkillCardList.vue
+++ b/web/src/components/extensions/SkillCardList.vue
@@ -2,7 +2,11 @@
-
+
远程安装
@@ -26,12 +30,17 @@
-
+
-
+
-
+
-
+
查看可安装 Skills
-
+
安装
- {{ remoteInstallStatusText }}
+ {{
+ remoteInstallStatusText
+ }}
共发现 {{ remoteSkillOptions.length }} 个 skills,可按输入内容筛选候选项。
@@ -174,9 +196,10 @@ const installedSkillCards = computed(() => {
...skill,
sourceType: 'builtin',
sourceLabel: '内置',
- status: skill.status === 'update_available'
- ? { label: '更新可用', level: 'warning' }
- : { label: '已安装', level: 'success' }
+ status:
+ skill.status === 'update_available'
+ ? { label: '更新可用', level: 'warning' }
+ : { label: '已安装', level: 'success' }
}
])
)
@@ -194,7 +217,9 @@ const installedSkillCards = computed(() => {
const filteredInstalledSkills = computed(() => installedSkillCards.value.filter(matchesSearch))
const filteredUninstalledBuiltinSkills = computed(() => {
- return (builtinSkills.value || []).filter((skill) => skill.status === 'not_installed' && matchesSearch(skill))
+ return (builtinSkills.value || []).filter(
+ (skill) => skill.status === 'not_installed' && matchesSearch(skill)
+ )
})
const filteredRemoteSkillOptions = computed(() =>
@@ -208,7 +233,8 @@ const remoteInstallStatusText = computed(() => {
if (!remoteInstallProgress.visible || !remoteInstallProgress.total) return ''
const progressText = `[${remoteInstallProgress.completed}/${remoteInstallProgress.total}]`
const currentSkill = remoteInstallProgress.currentSkill || ''
- const failedText = remoteInstallProgress.failed > 0 ? `, ${remoteInstallProgress.failed} failed` : ''
+ const failedText =
+ remoteInstallProgress.failed > 0 ? `, ${remoteInstallProgress.failed} failed` : ''
return `${progressText} ${currentSkill}${failedText}`.trim()
})
@@ -401,12 +427,16 @@ onMounted(() => {
fetchSkills()
})
-defineExpose({ fetchSkills, handleImportUpload, openRemoteInstallModal: handleOpenRemoteInstall, loading })
+defineExpose({
+ fetchSkills,
+ handleImportUpload,
+ openRemoteInstallModal: handleOpenRemoteInstall,
+ loading
+})
\ No newline at end of file
+
diff --git a/web/src/components/extensions/SkillDetailView.vue b/web/src/components/extensions/SkillDetailView.vue
index dec68b95..449a75ce 100644
--- a/web/src/components/extensions/SkillDetailView.vue
+++ b/web/src/components/extensions/SkillDetailView.vue
@@ -19,7 +19,11 @@
-
+
{{ currentSkillStatusLabel }}
@@ -79,9 +85,15 @@
@@ -127,7 +139,11 @@
@@ -270,11 +307,17 @@ const dependencyForm = reactive({
})
const isInstalledSkill = computed(() => {
- return !!(currentSkill.value && (currentSkill.value.installed_record || currentSkill.value.dir_path))
+ return !!(
+ currentSkill.value &&
+ (currentSkill.value.installed_record || currentSkill.value.dir_path)
+ )
})
const isBuiltinInstalledSkill = computed(() => {
- return !!(isInstalledSkill.value && (currentSkill.value?.is_builtin || currentSkill.value?.installed_record))
+ return !!(
+ isInstalledSkill.value &&
+ (currentSkill.value?.is_builtin || currentSkill.value?.installed_record)
+ )
})
const currentSkillStatusLabel = computed(() => {
@@ -312,7 +355,9 @@ const mcpDependencyOptions = computed(() =>
(dependencyOptions.mcps || []).map((i) => ({ label: i, value: i }))
)
const skillDependencyOptions = computed(() =>
- (dependencyOptions.skills || []).filter((s) => s !== currentSkill.value?.slug).map((i) => ({ label: i, value: i }))
+ (dependencyOptions.skills || [])
+ .filter((s) => s !== currentSkill.value?.slug)
+ .map((i) => ({ label: i, value: i }))
)
const goBack = () => {
@@ -451,7 +496,13 @@ const handleTreeSelect = async (keys, info) => {
}
const saveCurrentFile = async () => {
- if (!currentSkill.value || !selectedPath.value || selectedIsDir.value || isBuiltinInstalledSkill.value) return
+ if (
+ !currentSkill.value ||
+ !selectedPath.value ||
+ selectedIsDir.value ||
+ isBuiltinInstalledSkill.value
+ )
+ return
savingFile.value = true
try {
await skillApi.updateSkillFile(currentSkill.value.slug, {
@@ -521,7 +572,11 @@ const handleUpdateBuiltin = async (record) => {
const confirmDeleteSkill = () => {
const target = currentSkill.value
if (!target) return
- const isBuiltinTarget = !!(target?.is_builtin || target?.installed_record || target?.sourceType === 'builtin')
+ const isBuiltinTarget = !!(
+ target?.is_builtin ||
+ target?.installed_record ||
+ target?.sourceType === 'builtin'
+ )
const actionText = isBuiltinTarget ? '卸载' : '删除'
Modal.confirm({
title: `确认${actionText}技能「${target.slug}」?`,
@@ -840,4 +895,4 @@ onMounted(() => {
.pt-12 {
padding-top: 12px;
}
-
\ No newline at end of file
+
diff --git a/web/src/components/extensions/SubagentCardList.vue b/web/src/components/extensions/SubagentCardList.vue
index b0d2fad8..ca9629cc 100644
--- a/web/src/components/extensions/SubagentCardList.vue
+++ b/web/src/components/extensions/SubagentCardList.vue
@@ -14,7 +14,10 @@
-
+
@@ -27,7 +30,7 @@
:title="agent.name"
:description="agent.description || '暂无描述'"
:default-icon="BotIcon"
- :tags="agent.is_builtin ? [{ name: '内置' }] : [{name: '添加'}]"
+ :tags="agent.is_builtin ? [{ name: '内置' }] : [{ name: '添加' }]"
:status="{ label: '已添加', level: 'success' }"
@click="navigateToDetail(agent)"
>
@@ -42,7 +45,7 @@
:title="agent.name"
:description="agent.description || '暂无描述'"
:default-icon="BotIcon"
- :tags="agent.is_builtin ? [{ name: '内置' }] : [{name: '添加'}]"
+ :tags="agent.is_builtin ? [{ name: '内置' }] : [{ name: '添加' }]"
action-label="添加"
@click="navigateToDetail(agent)"
@action-click="handleSetAgentEnabled(agent, true)"
@@ -88,7 +91,9 @@
class="model-selector-full"
@select-model="handleModelSelect"
/>
-
清空
+
清空
@@ -259,4 +264,4 @@ defineExpose({ fetchSubAgents, loading })
width: 100%;
}
}
-
\ No newline at end of file
+
diff --git a/web/src/components/extensions/SubagentDetailView.vue b/web/src/components/extensions/SubagentDetailView.vue
index a271389c..12e886f7 100644
--- a/web/src/components/extensions/SubagentDetailView.vue
+++ b/web/src/components/extensions/SubagentDetailView.vue
@@ -140,7 +140,11 @@
>
-
+
@@ -166,7 +170,9 @@
class="model-selector-full"
@select-model="handleModelSelect"
/>
- 清空
+ 清空
@@ -353,4 +359,4 @@ onMounted(() => {
width: 100%;
}
}
-
\ No newline at end of file
+
diff --git a/web/src/components/extensions/ToolsCardList.vue b/web/src/components/extensions/ToolsCardList.vue
index d50a2fe6..b2bd419a 100644
--- a/web/src/components/extensions/ToolsCardList.vue
+++ b/web/src/components/extensions/ToolsCardList.vue
@@ -219,4 +219,4 @@ defineExpose({ fetchTools, loading })
.config-guide {
white-space: pre-line;
}
-
\ No newline at end of file
+
diff --git a/web/src/components/shared/PageHeader.vue b/web/src/components/shared/PageHeader.vue
index aeded796..ca7f66d6 100644
--- a/web/src/components/shared/PageHeader.vue
+++ b/web/src/components/shared/PageHeader.vue
@@ -114,7 +114,9 @@ function emitChange(item) {
line-height: 1;
text-decoration: none;
cursor: pointer;
- transition: background-color 0.2s ease, color 0.2s ease;
+ transition:
+ background-color 0.2s ease,
+ color 0.2s ease;
&:hover {
color: var(--gray-900);
diff --git a/web/src/composables/useModelStatus.js b/web/src/composables/useModelStatus.js
index 5392a94f..950e5163 100644
--- a/web/src/composables/useModelStatus.js
+++ b/web/src/composables/useModelStatus.js
@@ -23,7 +23,8 @@ export function useModelStatus() {
const getStatusTooltip = (key) => {
const status = statusMap[key]
if (!status) return '状态未知'
- const text = { available: '可用', unavailable: '不可用', error: '错误' }[status.status] || '未知'
+ const text =
+ { available: '可用', unavailable: '不可用', error: '错误' }[status.status] || '未知'
return `${text}: ${status.message || '无详细信息'}`
}
@@ -44,5 +45,12 @@ export function useModelStatus() {
}
}
- return { statusMap, getStatusIcon, getStatusClass, getStatusTooltip, checkV2Status, checkV2Statuses }
-}
\ No newline at end of file
+ return {
+ statusMap,
+ getStatusIcon,
+ getStatusClass,
+ getStatusTooltip,
+ checkV2Status,
+ checkV2Statuses
+ }
+}
diff --git a/web/src/utils/modelIcon.js b/web/src/utils/modelIcon.js
index 2a7bf4cb..6788629b 100644
--- a/web/src/utils/modelIcon.js
+++ b/web/src/utils/modelIcon.js
@@ -29,4 +29,4 @@ export const modelIcons = {
zhipu: `${ICON_BASE}/zhipu-color.svg`,
zhipuai: `${ICON_BASE}/zhipu-color.svg`,
'zhipuai-coding-plan': `${ICON_BASE}/zhipu-color.svg`
-}
+}
diff --git a/web/src/views/ExtensionsView.vue b/web/src/views/ExtensionsView.vue
index de26d761..8540eeec 100644
--- a/web/src/views/ExtensionsView.vue
+++ b/web/src/views/ExtensionsView.vue
@@ -53,9 +53,11 @@ const extensionTabs = [
]
const isDetailPage = computed(() => {
- return route.path.startsWith('/extensions/mcp/') ||
+ return (
+ route.path.startsWith('/extensions/mcp/') ||
route.path.startsWith('/extensions/subagent/') ||
route.path.startsWith('/extensions/skill/')
+ )
})
const activeChildLoading = computed(() => {
@@ -91,4 +93,4 @@ watch(
}
}
}
-
\ No newline at end of file
+
diff --git a/web/src/views/ModelConfigView.vue b/web/src/views/ModelConfigView.vue
index 834982cb..974cd3a8 100644
--- a/web/src/views/ModelConfigView.vue
+++ b/web/src/views/ModelConfigView.vue
@@ -256,7 +256,6 @@ function getProviderInfo(provider) {
]
}
-
function getProviderStatus(provider) {
if (!provider.is_enabled) return { label: '未启用', level: 'info' }
if (provider.credential_status === 'warning') return { label: '凭证缺失', level: 'warning' }