mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-26 11:34:50 +02:00
[hAIk]: fix: create modelsSlice and register it in store to resolve ModelModeSelector TypeError on dashboard agent launch. Reuses SUBSCRIPTIONS_STATUS thunk instead of duplicating the fetch.
This commit is contained in:
@@ -5,7 +5,7 @@ import { ThemeProvider as MuiThemeProvider, CssBaseline } from '@mui/material';
|
||||
import { store } from '../shared/state/store';
|
||||
import { useAppDispatch, useAppSelector } from '@/shared/hooks';
|
||||
import { GET_SETTINGS } from '@/shared/backend-bridge/apps/settings';
|
||||
// import { fetchModels } from '@/shared/state/modelsSlice';
|
||||
import { SUBSCRIPTIONS_STATUS } from '@/shared/backend-bridge/apps/subscriptions';
|
||||
import {
|
||||
setAppVersion,
|
||||
setUpdateAvailable,
|
||||
@@ -40,7 +40,7 @@ const SettingsLoader: React.FC<{ children: React.ReactNode }> = ({ children }) =
|
||||
const loaded = useAppSelector((s) => s.settings.loaded);
|
||||
useEffect(() => {
|
||||
dispatch(GET_SETTINGS());
|
||||
// dispatch(fetchModels());
|
||||
dispatch(SUBSCRIPTIONS_STATUS());
|
||||
}, [dispatch]);
|
||||
useEffect(() => {
|
||||
if (loaded) setThemeMode(theme as 'light' | 'dark');
|
||||
|
||||
@@ -52,10 +52,10 @@ interface Props {
|
||||
}
|
||||
|
||||
const ModelModeSelector: React.FC<Props> = ({
|
||||
mode, onModeChange, model, onModelChange, provider, onProviderChange,
|
||||
mode, onModeChange, model, onModelChange, onProviderChange,
|
||||
contextEstimate, ownerId, sessionId,
|
||||
autoRunMode, hasContent, isRunning, disabled, onSend, onStop,
|
||||
browseAndAttachFiles, queueLength = 0,
|
||||
browseAndAttachFiles,
|
||||
}) => {
|
||||
const c = useClaudeTokens();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useState, useEffect, useMemo, useCallback } from 'react';
|
||||
import { useAppDispatch, useAppSelector } from '@/shared/hooks';
|
||||
import { UPDATE_SETTINGS, AppSettings } from '@/shared/backend-bridge/apps/settings';
|
||||
import { closeSettingsModal } from '@/shared/state/settingsSlice';
|
||||
// import { fetchModels } from '@/shared/state/modelsSlice';
|
||||
import { SUBSCRIPTIONS_STATUS } from '@/shared/backend-bridge/apps/subscriptions';
|
||||
import { setChecking, setUpdateError } from '@/shared/state/updateSlice';
|
||||
import { LIST_MODES } from '@/shared/state/modesSlice';
|
||||
import { useClaudeTokens, useThemeMode } from '@/shared/styles/ThemeContext';
|
||||
@@ -35,7 +35,7 @@ export function useSettings() {
|
||||
const handleSave = async () => {
|
||||
await dispatch(UPDATE_SETTINGS(form));
|
||||
if (form.theme !== settings.theme) setThemeMode(form.theme);
|
||||
// dispatch(fetchModels());
|
||||
dispatch(SUBSCRIPTIONS_STATUS());
|
||||
setSaved(true);
|
||||
};
|
||||
const handleRequestClose = useCallback(() => {
|
||||
@@ -50,7 +50,7 @@ export function useSettings() {
|
||||
const handleSaveAndClose = useCallback(async () => {
|
||||
await dispatch(UPDATE_SETTINGS(form));
|
||||
if (form.theme !== settings.theme) setThemeMode(form.theme);
|
||||
// dispatch(fetchModels());
|
||||
dispatch(SUBSCRIPTIONS_STATUS());
|
||||
setSaved(true);
|
||||
setConfirmDiscard(false);
|
||||
dispatch(closeSettingsModal());
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import { SUBSCRIPTIONS_STATUS } from '@/shared/backend-bridge/apps/subscriptions';
|
||||
|
||||
interface ModelEntry {
|
||||
value: string;
|
||||
label: string;
|
||||
context_window: number;
|
||||
provider: string;
|
||||
}
|
||||
|
||||
interface ModelsState {
|
||||
byProvider: Record<string, ModelEntry[]>;
|
||||
loading: boolean;
|
||||
loaded: boolean;
|
||||
}
|
||||
|
||||
const initialState: ModelsState = { byProvider: {}, loading: false, loaded: false };
|
||||
|
||||
function groupByProvider(raw: any[]): Record<string, ModelEntry[]> {
|
||||
const grouped: Record<string, ModelEntry[]> = {};
|
||||
for (const m of raw) {
|
||||
const entry: ModelEntry = {
|
||||
value: m.value ?? m.id ?? '',
|
||||
label: m.label ?? m.value ?? '',
|
||||
context_window: m.context_window ?? 200_000,
|
||||
provider: m.provider ?? 'Unknown',
|
||||
};
|
||||
const key = entry.provider.charAt(0).toUpperCase() + entry.provider.slice(1);
|
||||
(grouped[key] ??= []).push(entry);
|
||||
}
|
||||
return grouped;
|
||||
}
|
||||
|
||||
const modelsSlice = createSlice({
|
||||
name: 'models',
|
||||
initialState,
|
||||
reducers: {},
|
||||
extraReducers: (builder) => {
|
||||
builder
|
||||
.addCase(SUBSCRIPTIONS_STATUS.pending, (state) => { state.loading = true; })
|
||||
.addCase(SUBSCRIPTIONS_STATUS.fulfilled, (state, action) => {
|
||||
state.loading = false;
|
||||
state.loaded = true;
|
||||
state.byProvider = groupByProvider((action.payload as any).models ?? []);
|
||||
})
|
||||
.addCase(SUBSCRIPTIONS_STATUS.rejected, (state) => { state.loading = false; state.loaded = true; });
|
||||
},
|
||||
});
|
||||
|
||||
export default modelsSlice.reducer;
|
||||
@@ -11,7 +11,7 @@ import dashboardLayoutReducer from './dashboardLayoutSlice';
|
||||
import dashboardsReducer from './dashboardsSlice';
|
||||
import appsReducer from './appsSlice';
|
||||
import updateReducer from './updateSlice';
|
||||
// import modelsReducer from './modelsSlice';
|
||||
import modelsReducer from './modelsSlice';
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
@@ -27,7 +27,7 @@ export const store = configureStore({
|
||||
dashboards: dashboardsReducer,
|
||||
apps: appsReducer,
|
||||
update: updateReducer,
|
||||
// models: modelsReducer,
|
||||
models: modelsReducer,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user