Improve pipeline monitoring and AI tab resilience

This commit is contained in:
Hyu
2026-07-02 16:34:11 +08:00
parent e32e515bc9
commit 0ce382fc8b
5 changed files with 407 additions and 303 deletions
@@ -67,6 +67,16 @@ import SettingsDialog, {
import ToolResourceSelectors from '@/app/home/components/dynamic-form/ToolResourceSelectors';
import { LANGBOT_MODELS_PROVIDER_REQUESTER } from '@/app/home/components/models-dialog/types';
function hasUsableUuid<T extends { uuid?: string | null }>(
item: T,
): item is T & { uuid: string } {
return typeof item.uuid === 'string' && item.uuid.trim().length > 0;
}
function hasUsableOptionName(option: { name?: string | null }): boolean {
return typeof option.name === 'string' && option.name.trim().length > 0;
}
export default function DynamicFormItemComponent({
config,
field,
@@ -104,7 +114,7 @@ export default function DynamicFormItemComponent({
httpClient
.getProviderLLMModels()
.then((resp) => {
setLlmModels(resp.models);
setLlmModels(resp.models.filter(hasUsableUuid));
})
.catch((err) => {
toast.error(t('models.getModelListError') + err.msg);
@@ -115,7 +125,7 @@ export default function DynamicFormItemComponent({
httpClient
.getProviderEmbeddingModels()
.then((resp) => {
setEmbeddingModels(resp.models);
setEmbeddingModels(resp.models.filter(hasUsableUuid));
})
.catch((err) => {
toast.error(t('embedding.getModelListError') + err.msg);
@@ -126,7 +136,7 @@ export default function DynamicFormItemComponent({
httpClient
.getProviderRerankModels()
.then((resp) => {
setRerankModels(resp.models);
setRerankModels(resp.models.filter(hasUsableUuid));
})
.catch((err) => {
toast.error('Failed to load rerank models: ' + err.msg);
@@ -230,7 +240,7 @@ export default function DynamicFormItemComponent({
httpClient
.getKnowledgeBases()
.then((resp) => {
setKnowledgeBases(resp.bases);
setKnowledgeBases(resp.bases.filter(hasUsableUuid));
})
.catch((err) => {
toast.error(t('knowledge.getKnowledgeBaseListError') + err.msg);
@@ -243,7 +253,7 @@ export default function DynamicFormItemComponent({
httpClient
.getBots()
.then((resp) => {
setBots(resp.bots);
setBots(resp.bots.filter(hasUsableUuid));
})
.catch((err) => {
toast.error(t('bots.getBotListError') + err.msg);
@@ -388,15 +398,17 @@ export default function DynamicFormItemComponent({
</SelectTrigger>
<SelectContent>
<SelectGroup>
{config.options?.map((option) => (
<SelectItem
key={option.name}
value={option.name}
description={option.name}
>
{extractI18nObject(option.label)}
</SelectItem>
))}
{config.options
?.filter(hasUsableOptionName)
.map((option) => (
<SelectItem
key={option.name}
value={option.name}
description={option.name}
>
{extractI18nObject(option.label)}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
@@ -1176,7 +1188,8 @@ export default function DynamicFormItemComponent({
case DynamicFormItemType.KNOWLEDGE_BASE_SELECTOR:
// Group KBs by Knowledge Engine name
const kbsByEngine = knowledgeBases.reduce(
const validKnowledgeBases = knowledgeBases.filter(hasUsableUuid);
const kbsByEngine = validKnowledgeBases.reduce(
(acc, kb) => {
const engineName = kb.knowledge_engine?.name
? extractI18nObject(kb.knowledge_engine.name)
@@ -1187,7 +1200,7 @@ export default function DynamicFormItemComponent({
acc[engineName].push(kb);
return acc;
},
{} as Record<string, typeof knowledgeBases>,
{} as Record<string, typeof validKnowledgeBases>,
);
return (
@@ -1195,7 +1208,7 @@ export default function DynamicFormItemComponent({
<SelectTrigger className="min-w-0 bg-[#ffffff] dark:bg-[#2a2a2e]">
{field.value && field.value !== '__none__' ? (
(() => {
const selectedKb = knowledgeBases.find(
const selectedKb = validKnowledgeBases.find(
(kb) => kb.uuid === field.value,
);
return (
@@ -1224,7 +1237,7 @@ export default function DynamicFormItemComponent({
<SelectGroup key={engineName}>
<SelectLabel>{engineName}</SelectLabel>
{kbs.map((base) => (
<SelectItem key={base.uuid} value={base.uuid ?? ''}>
<SelectItem key={base.uuid} value={base.uuid}>
<div className="flex items-center gap-2">
{base.emoji && (
<span className="text-sm shrink-0">{base.emoji}</span>
@@ -1241,7 +1254,8 @@ export default function DynamicFormItemComponent({
case DynamicFormItemType.KNOWLEDGE_BASE_MULTI_SELECTOR:
// Group KBs by Knowledge Engine name for multi-selector
const multiKbsByEngine = knowledgeBases.reduce(
const validMultiKnowledgeBases = knowledgeBases.filter(hasUsableUuid);
const multiKbsByEngine = validMultiKnowledgeBases.reduce(
(acc, kb) => {
const engineName = kb.knowledge_engine?.name
? extractI18nObject(kb.knowledge_engine.name)
@@ -1252,7 +1266,7 @@ export default function DynamicFormItemComponent({
acc[engineName].push(kb);
return acc;
},
{} as Record<string, typeof knowledgeBases>,
{} as Record<string, typeof validMultiKnowledgeBases>,
);
return (
@@ -1261,7 +1275,7 @@ export default function DynamicFormItemComponent({
{field.value && field.value.length > 0 ? (
<div className="min-w-0 space-y-2">
{field.value.map((kbId: string) => {
const currentKb = knowledgeBases.find(
const currentKb = validMultiKnowledgeBases.find(
(base) => base.uuid === kbId,
);
if (!currentKb) return null;
@@ -1348,14 +1362,14 @@ export default function DynamicFormItemComponent({
</div>
{kbs.map((base) => {
const isSelected = tempSelectedKBIds.includes(
base.uuid ?? '',
base.uuid,
);
return (
<div
key={base.uuid}
className="flex items-center gap-3 rounded-lg border p-3 hover:bg-accent cursor-pointer"
onClick={() => {
const kbId = base.uuid ?? '';
const kbId = base.uuid;
setTempSelectedKBIds((prev) =>
prev.includes(kbId)
? prev.filter((id) => id !== kbId)
@@ -1417,8 +1431,8 @@ export default function DynamicFormItemComponent({
</SelectTrigger>
<SelectContent>
<SelectGroup>
{bots.map((bot) => (
<SelectItem key={bot.uuid} value={bot.uuid ?? ''}>
{bots.filter(hasUsableUuid).map((bot) => (
<SelectItem key={bot.uuid} value={bot.uuid}>
{bot.name}
</SelectItem>
))}