Skip to content

Commit a8250dd

Browse files
authored
fix(ui): improve error handling for model_providers query (#1314)
Signed-off-by: Petr Kadlec <[email protected]>
1 parent 853280e commit a8250dd

File tree

5 files changed

+37
-75
lines changed

5 files changed

+37
-75
lines changed

apps/beeai-ui/src/contexts/QueryProvider/types.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ import type { QueryKey } from '@tanstack/react-query';
77

88
import type { useHandleError } from '#hooks/useHandleError.ts';
99

10+
export interface QueryMetadataError {
11+
title?: string;
12+
message?: string;
13+
includeErrorMessage?: boolean;
14+
}
1015
export interface QueryMetadata extends Record<string, unknown> {
11-
errorToast?:
12-
| false
13-
| {
14-
title?: string;
15-
includeErrorMessage?: boolean;
16-
};
16+
errorToast?: false | QueryMetadataError;
1717
}
1818

1919
export type HandleError = ReturnType<typeof useHandleError>;

apps/beeai-ui/src/contexts/Toast/ToastProvider.module.scss

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@
4545
margin-block-start: $spacing-02;
4646
font-size: rem(12px);
4747
font-family: font-family('mono');
48-
background: $background-inverse;
49-
color: $text-inverse;
50-
padding: $spacing-03;
48+
padding-block: $spacing-03;
5149
max-block-size: 10.2rem;
5250
}

apps/beeai-ui/src/hooks/useHandleError.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ export function useHandleError() {
3232

3333
addToast({
3434
title: errorToast?.title ?? errorTitle,
35-
subtitle: errorMessage,
35+
subtitle: errorToast?.message,
36+
apiError: errorMessage,
3637
});
3738
} else {
3839
console.error(error);

apps/beeai-ui/src/modules/platform-context/api/mutations/useMatchProviders.ts

Lines changed: 16 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -17,67 +17,23 @@ const MAX_PROVIDERS = 5;
1717

1818
type MatchProvidersResult = Record<string, string[]>;
1919

20-
export function useMatchEmbeddingProviders(
21-
demands: EmbeddingDemand['embedding_demands'],
22-
onSuccess: (data: MatchProvidersResult) => void,
23-
) {
24-
const {
25-
config: { featureFlags },
26-
} = useApp();
27-
const demandKey = Object.entries(demands)
28-
.map(([key, value]) => [key, ...(value.suggested ?? [])])
29-
.join();
30-
31-
const query = useQuery({
32-
queryKey: ['matchEmbeddingProviders', demandKey],
33-
enabled: featureFlags.ModelProviders && Object.keys(demands).length > 0,
34-
queryFn: async () => {
35-
const demandKeys = Object.keys(demands);
36-
37-
const allProviders = await Promise.all(
38-
demandKeys.map(async (demandKey) => {
39-
const result = await matchProviders({
40-
suggested_models: demands[demandKey].suggested ?? [],
41-
capability: ModelCapability.Embedding,
42-
});
43-
return {
44-
key: demandKey,
45-
providers: result?.items.map((item) => item.model_id).slice(0, MAX_PROVIDERS) ?? [],
46-
};
47-
}),
48-
);
49-
50-
return allProviders.reduce<MatchProvidersResult>((acc, { key, providers }) => {
51-
acc[key] = providers;
52-
return acc;
53-
}, {});
54-
},
55-
});
56-
57-
const { isSuccess, data } = query;
58-
59-
useEffect(() => {
60-
if (isSuccess && data) {
61-
onSuccess(data);
62-
}
63-
}, [isSuccess, data, onSuccess]);
64-
65-
return query;
20+
interface Props {
21+
demands: EmbeddingDemand['embedding_demands'] | LLMDemand['llm_demands'];
22+
onSuccess: (data: MatchProvidersResult) => void;
23+
capability: ModelCapability;
6624
}
6725

68-
export function useMatchLLMProviders(
69-
demands: LLMDemand['llm_demands'],
70-
onSuccess: (data: MatchProvidersResult) => void,
71-
) {
26+
export function useMatchProviders({ demands, onSuccess, capability }: Props) {
7227
const {
73-
config: { featureFlags },
28+
config: { featureFlags, isAuthEnabled },
7429
} = useApp();
30+
7531
const demandKey = Object.entries(demands)
7632
.map(([key, value]) => [key, ...(value.suggested ?? [])])
7733
.join();
7834

7935
const query = useQuery({
80-
queryKey: ['matchLLMProviders', demandKey],
36+
queryKey: [capability === ModelCapability.Embedding ? 'matchEmbeddingProviders' : 'matchLLMProviders', demandKey],
8137
enabled: featureFlags.ModelProviders && Object.keys(demands).length > 0,
8238
queryFn: async () => {
8339
const demandKeys = Object.keys(demands);
@@ -86,7 +42,7 @@ export function useMatchLLMProviders(
8642
demandKeys.map(async (demandKey) => {
8743
const result = await matchProviders({
8844
suggested_models: demands[demandKey].suggested ?? [],
89-
capability: ModelCapability.Llm,
45+
capability,
9046
});
9147
return {
9248
key: demandKey,
@@ -100,6 +56,13 @@ export function useMatchLLMProviders(
10056
return acc;
10157
}, {});
10258
},
59+
meta: {
60+
errorToast: {
61+
title: 'Model providers query failed',
62+
message: !isAuthEnabled ? 'Have you configured providers by running `beeai model setup`?' : undefined,
63+
includeErrorMessage: true,
64+
},
65+
},
10366
});
10467

10568
const { isSuccess, data } = query;

apps/beeai-ui/src/modules/runs/contexts/agent-demands/AgentDemandsProvider.tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@ import { type PropsWithChildren, useCallback, useEffect, useState } from 'react'
88
import type { AgentA2AClient } from '#api/a2a/types.ts';
99
import { useApp } from '#contexts/App/index.ts';
1010
import { useCreateContextToken } from '#modules/platform-context/api/mutations/useCreateContextToken.ts';
11-
import {
12-
useMatchEmbeddingProviders,
13-
useMatchLLMProviders,
14-
} from '#modules/platform-context/api/mutations/useMatchProviders.ts';
11+
import { useMatchProviders } from '#modules/platform-context/api/mutations/useMatchProviders.ts';
1512
import { usePlatformContext } from '#modules/platform-context/contexts/index.ts';
13+
import { ModelCapability } from '#modules/platform-context/types.ts';
1614

1715
import { useAgentSecrets } from '../agent-secrets';
1816
import { AgentDemandsContext } from './agent-demands-context';
@@ -54,10 +52,11 @@ export function AgentDemandsProvider<UIGenericPart>({
5452
[setSelectedLLMProviders],
5553
);
5654

57-
const { data: matchedLLMProviders } = useMatchLLMProviders(
58-
agentClient?.llmDemands ?? {},
59-
setDefaultSelectedLLMProviders,
60-
);
55+
const { data: matchedLLMProviders } = useMatchProviders({
56+
demands: agentClient?.llmDemands ?? {},
57+
onSuccess: setDefaultSelectedLLMProviders,
58+
capability: ModelCapability.Llm,
59+
});
6160

6261
const setDefaultSelectedEmbeddingProviders = useCallback(
6362
(data: Record<string, string[]>) => {
@@ -76,10 +75,11 @@ export function AgentDemandsProvider<UIGenericPart>({
7675
[setSelectedEmbeddingProviders],
7776
);
7877

79-
const { data: matchedEmbeddingProviders } = useMatchEmbeddingProviders(
80-
agentClient?.embeddingDemands ?? {},
81-
setDefaultSelectedEmbeddingProviders,
82-
);
78+
const { data: matchedEmbeddingProviders } = useMatchProviders({
79+
demands: agentClient?.embeddingDemands ?? {},
80+
onSuccess: setDefaultSelectedEmbeddingProviders,
81+
capability: ModelCapability.Embedding,
82+
});
8383

8484
const selectLLMProvider = useCallback(
8585
(key: string, value: string) => {

0 commit comments

Comments
 (0)