-
Notifications
You must be signed in to change notification settings - Fork 449
Expand file tree
/
Copy pathuseUpdateSettingsMutation.ts
More file actions
130 lines (116 loc) · 3.71 KB
/
Copy pathuseUpdateSettingsMutation.ts
File metadata and controls
130 lines (116 loc) · 3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import {
type UseMutationOptions,
useMutation,
useQueryClient,
} from "@tanstack/react-query";
import { useGetCurrentProviderModelsQuery } from "../queries/useGetModelsQuery";
import type { Settings } from "../queries/useGetSettingsQuery";
export interface UpdateSettingsRequest {
// Agent settings
llm_model?: string;
llm_provider?: string;
system_prompt?: string;
// Knowledge settings
chunk_size?: number;
chunk_overlap?: number;
table_structure?: boolean;
ocr?: boolean;
picture_descriptions?: boolean;
disable_ingest_with_langflow?: boolean;
embedding_model?: string;
embedding_provider?: string;
// Provider-specific settings (for dialogs)
model_provider?: string; // Deprecated, kept for backward compatibility
api_key?: string;
endpoint?: string;
project_id?: string;
// Provider-specific API keys
openai_api_key?: string;
anthropic_api_key?: string;
watsonx_api_key?: string;
watsonx_endpoint?: string;
watsonx_project_id?: string;
ollama_endpoint?: string;
remove_ollama_config?: boolean;
remove_openai_config?: boolean;
remove_anthropic_config?: boolean;
remove_watsonx_config?: boolean;
// Bypass the "this provider's embedding models are still in use" guard.
force_remove?: boolean;
}
export interface AffectedEmbeddingModel {
model: string;
doc_count: number;
}
// Typed error that preserves the structured 409 payload returned by
// POST /api/settings when removing a provider whose embedding models are
// still referenced by indexed documents.
export class UpdateSettingsError extends Error {
readonly status: number;
readonly code?: string;
readonly affectedProvider?: string;
readonly affectedModels?: AffectedEmbeddingModel[];
constructor(status: number, data: Record<string, unknown>) {
const message =
typeof data.error === "string" ? data.error : "Failed to update settings";
super(message);
this.name = "UpdateSettingsError";
this.status = status;
this.code = typeof data.code === "string" ? data.code : undefined;
this.affectedProvider =
typeof data.affected_provider === "string"
? data.affected_provider
: undefined;
this.affectedModels = Array.isArray(data.affected_models)
? (data.affected_models as AffectedEmbeddingModel[])
: undefined;
}
}
export const isEmbeddingProviderInUseError = (
err: unknown,
): err is UpdateSettingsError =>
err instanceof UpdateSettingsError &&
err.code === "embedding_provider_in_use" &&
Array.isArray(err.affectedModels) &&
err.affectedModels.length > 0;
export interface UpdateSettingsResponse {
message: string;
settings: Settings;
}
export const useUpdateSettingsMutation = (
options?: Omit<
UseMutationOptions<UpdateSettingsResponse, Error, UpdateSettingsRequest>,
"mutationFn"
>,
) => {
const queryClient = useQueryClient();
const { refetch: refetchModels } = useGetCurrentProviderModelsQuery();
async function updateSettings(
variables: UpdateSettingsRequest,
): Promise<UpdateSettingsResponse> {
const response = await fetch("/api/settings", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(variables),
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new UpdateSettingsError(response.status, errorData);
}
return response.json();
}
return useMutation({
mutationFn: updateSettings,
onSuccess: (...args) => {
queryClient.invalidateQueries({
queryKey: ["settings"],
});
refetchModels(); // Refetch models for the settings page
options?.onSuccess?.(...args);
},
onError: options?.onError,
onSettled: options?.onSettled,
});
};