mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-07-18 02:16:07 +00:00
Improve pipeline monitoring and AI tab resilience
This commit is contained in:
@@ -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>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user