Skip to content

Commit 70af97e

Browse files
committed
add per-tab model persistence and selection functionality
1 parent 8cedf06 commit 70af97e

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

gui/src/components/TabBar/TabBar.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { XMarkIcon } from "@heroicons/react/24/outline";
22
import React, { useCallback, useEffect } from "react";
33
import { useDispatch, useSelector } from "react-redux";
4+
import { useAppSelector } from "../../redux/hooks";
45
import styled from "styled-components";
56
import { defaultBorderRadius } from "..";
67
import { newSession } from "../../redux/slices/sessionSlice";
@@ -10,10 +11,14 @@ import {
1011
removeTab,
1112
setActiveTab,
1213
setTabs,
14+
setTabModel,
1315
} from "../../redux/slices/tabsSlice";
1416
import { AppDispatch, RootState } from "../../redux/store";
1517
import { loadSession, saveCurrentSession } from "../../redux/thunks/session";
1618
import { varWithFallback } from "../../styles/theme";
19+
import { useAuth } from "../../context/Auth";
20+
import { selectSelectedChatModel } from "../../redux/slices/configSlice";
21+
import { updateSelectedModelByRole } from "../../redux/thunks/updateSelectedModelByRole";
1722

1823
// Haven't set up theme colors for tabs yet
1924
// Will keep it simple and choose from existing ones. Comments show vars we could use
@@ -137,6 +142,11 @@ export const TabBar = React.forwardRef<HTMLDivElement>((_, ref) => {
137142
(state: RootState) => state.session.history.length > 0,
138143
);
139144
const tabs = useSelector((state: RootState) => state.tabs.tabs);
145+
const selectedModel = useAppSelector(selectSelectedChatModel);
146+
const { selectedProfile } = useAuth();
147+
const activeTab = tabs.find((tab) => tab.isActive);
148+
const activeTabId = activeTab?.id;
149+
const activeTabModel = activeTab?.modelTitle;
140150

141151
// Simple UUID generator for our needs
142152
const generateId = useCallback(() => {
@@ -155,6 +165,15 @@ export const TabBar = React.forwardRef<HTMLDivElement>((_, ref) => {
155165
);
156166
}, [currentSessionId, currentSessionTitle]);
157167

168+
// Persist selected model into the active tab in Redux
169+
useEffect(() => {
170+
if (activeTabId && selectedModel?.title) {
171+
dispatch(
172+
setTabModel({ id: activeTabId, modelTitle: selectedModel.title }),
173+
);
174+
}
175+
}, [activeTabId, selectedModel?.title, dispatch]);
176+
158177
const handleNewTab = async () => {
159178
// Save current session before creating new one
160179
if (hasHistory) {
@@ -171,6 +190,7 @@ export const TabBar = React.forwardRef<HTMLDivElement>((_, ref) => {
171190
title: `Chat ${tabs.length + 1}`,
172191
isActive: true,
173192
sessionId: undefined,
193+
modelTitle: selectedModel?.title,
174194
}),
175195
);
176196
};
@@ -196,6 +216,16 @@ export const TabBar = React.forwardRef<HTMLDivElement>((_, ref) => {
196216
}
197217

198218
dispatch(setActiveTab(id));
219+
// restore model for this tab
220+
if (targetTab.modelTitle && selectedProfile) {
221+
void dispatch(
222+
updateSelectedModelByRole({
223+
selectedProfile,
224+
role: "chat",
225+
modelTitle: targetTab.modelTitle,
226+
}),
227+
);
228+
}
199229
};
200230

201231
const handleTabClose = async (id: string) => {

gui/src/redux/slices/tabsSlice.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export interface Tab {
55
title: string;
66
isActive: boolean;
77
sessionId?: string;
8+
modelTitle?: string; // store per-tab model
89
}
910

1011
interface TabsState {
@@ -17,6 +18,7 @@ const initialState: TabsState = {
1718
id: Date.now().toString(36) + Math.random().toString(36).substring(2),
1819
title: "Chat 1",
1920
isActive: true,
21+
modelTitle: undefined,
2022
},
2123
],
2224
};
@@ -37,6 +39,16 @@ export const tabsSlice = createSlice({
3739
tab.id === id ? { ...tab, ...updates } : tab,
3840
);
3941
},
42+
// Set the model title for a specific tab
43+
setTabModel: (
44+
state,
45+
action: PayloadAction<{ id: string; modelTitle: string }>,
46+
) => {
47+
const { id, modelTitle } = action.payload;
48+
state.tabs = state.tabs.map((tab) =>
49+
tab.id === id ? { ...tab, modelTitle } : tab,
50+
);
51+
},
4052
addTab: (state, action: PayloadAction<Tab>) => {
4153
state.tabs = state.tabs
4254
.map((tab) => ({
@@ -122,6 +134,7 @@ export const tabsSlice = createSlice({
122134
title: currentSessionTitle,
123135
isActive: true,
124136
sessionId: currentSessionId,
137+
modelTitle: undefined,
125138
});
126139
}
127140
},
@@ -131,6 +144,7 @@ export const tabsSlice = createSlice({
131144
export const {
132145
setTabs,
133146
updateTab,
147+
setTabModel,
134148
addTab,
135149
removeTab,
136150
setActiveTab,

0 commit comments

Comments
 (0)