Skip to content

Commit 368dda7

Browse files
committed
refactor: extract shared model selection logic into useModelSelection
- Create useModelSelection hook for settings-based model management - Exposes settingsDoc to avoid duplicate Fireproof queries - Update useNewSessionChat to use shared hook (-12 lines) - Update useSimpleChat to use shared hook (-5 lines) - Remove duplicate useFireproof calls for settings database - Single source of truth for model selection across app
1 parent dd36426 commit 368dda7

File tree

3 files changed

+61
-46
lines changed

3 files changed

+61
-46
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { useState } from "react";
2+
import { useFireproof } from "use-fireproof";
3+
import { DEFAULT_CODING_MODEL, type UserSettings } from "@vibes.diy/prompts";
4+
import { VibesDiyEnv } from "../config/env.js";
5+
6+
/**
7+
* Hook to manage model selection with global settings fallback
8+
* Shared by useNewSessionChat and useSimpleChat
9+
*/
10+
export function useModelSelection() {
11+
const { useDocument } = useFireproof(VibesDiyEnv.SETTINGS_DBNAME());
12+
const { doc: settingsDoc } = useDocument<UserSettings>({
13+
_id: "user_settings",
14+
});
15+
16+
const [selectedModel, setSelectedModel] = useState<string | undefined>(
17+
undefined,
18+
);
19+
20+
// Determine effective model: user selection > global setting > default
21+
const effectiveModel =
22+
selectedModel || settingsDoc?.model || DEFAULT_CODING_MODEL;
23+
24+
return {
25+
selectedModel,
26+
setSelectedModel,
27+
effectiveModel,
28+
globalModel: settingsDoc?.model || DEFAULT_CODING_MODEL,
29+
showModelPickerInChat: settingsDoc?.showModelPickerInChat || false,
30+
settingsDoc, // Expose for consumers that need other settings properties
31+
};
32+
}

vibes.diy/pkg/app/hooks/useNewSessionChat.ts

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,18 @@
1-
import {
2-
DEFAULT_CODING_MODEL,
3-
type NewSessionChatState,
4-
type UserSettings,
5-
} from "@vibes.diy/prompts";
1+
import { type NewSessionChatState } from "@vibes.diy/prompts";
62
import { useCallback, useRef, useState } from "react";
73
import { useNavigate } from "react-router";
8-
import { useFireproof } from "use-fireproof";
9-
import { VibesDiyEnv } from "../config/env.js";
104
import { trackEvent } from "../utils/analytics.js";
5+
import { useModelSelection } from "./useModelSelection.js";
116

12-
// investigate if this can be combined with useSimpleChat() by passing an option on new sessions
137
export function useNewSessionChat(
148
onSessionCreate: (sessionId: string) => void,
159
): NewSessionChatState {
1610
const [input, setInput] = useState("");
1711
const [isStreaming, setIsStreaming] = useState(false);
18-
const [selectedModel, setSelectedModel] = useState<string | undefined>(
19-
undefined,
20-
);
2112
const inputRef = useRef<HTMLTextAreaElement | null>(null);
2213
const navigate = useNavigate();
2314

24-
// Get settings document to read showModelPickerInChat preference
25-
const { useDocument } = useFireproof(VibesDiyEnv.SETTINGS_DBNAME());
26-
const { doc: settingsDoc } = useDocument<UserSettings>({
27-
_id: "user_settings",
28-
});
15+
const modelSelection = useModelSelection();
2916

3017
const sendMessage = useCallback(
3118
async (textOverride?: string) => {
@@ -49,15 +36,15 @@ export function useNewSessionChat(
4936
urlParams.set("prompt", userMessage);
5037

5138
// If user selected a specific model, pass it to the new session
52-
if (selectedModel) {
53-
urlParams.set("model", selectedModel);
39+
if (modelSelection.selectedModel) {
40+
urlParams.set("model", modelSelection.selectedModel);
5441
}
5542

5643
const targetUrl = `/chat/${newSessionId}?${urlParams.toString()}`;
5744

5845
// Track session creation before navigation
5946
trackEvent("new_session_created", {
60-
model: selectedModel || effectiveModel,
47+
model: modelSelection.effectiveModel,
6148
});
6249

6350
// Delay navigation slightly to allow analytics event to flush
@@ -68,7 +55,13 @@ export function useNewSessionChat(
6855
setIsStreaming(false);
6956
}
7057
},
71-
[input, selectedModel, settingsDoc, onSessionCreate, navigate],
58+
[
59+
input,
60+
modelSelection.selectedModel,
61+
modelSelection.effectiveModel,
62+
onSessionCreate,
63+
navigate,
64+
],
7265
);
7366

7467
// Stub functions that are not needed for new session creation
@@ -94,15 +87,11 @@ export function useNewSessionChat(
9487

9588
const updateSelectedModel = useCallback(
9689
async (modelId: string): Promise<void> => {
97-
setSelectedModel(modelId);
90+
modelSelection.setSelectedModel(modelId);
9891
},
99-
[],
92+
[modelSelection],
10093
);
10194

102-
// Determine effective model: user selection > global setting > default
103-
const effectiveModel =
104-
selectedModel || settingsDoc?.model || DEFAULT_CODING_MODEL;
105-
10695
return {
10796
input,
10897
setInput,
@@ -114,10 +103,10 @@ export function useNewSessionChat(
114103
codeReady: false, // No code ready in new session
115104
title: "", // No title for new session
116105
sessionId: null, // No session ID until created
117-
showModelPickerInChat: settingsDoc?.showModelPickerInChat || false,
118-
effectiveModel,
119-
globalModel: settingsDoc?.model || DEFAULT_CODING_MODEL,
120-
selectedModel,
106+
showModelPickerInChat: modelSelection.showModelPickerInChat,
107+
effectiveModel: modelSelection.effectiveModel,
108+
globalModel: modelSelection.globalModel,
109+
selectedModel: modelSelection.selectedModel,
121110
updateSelectedModel,
122111
saveCodeAsAiMessage,
123112
updateTitle,

vibes.diy/pkg/app/hooks/useSimpleChat.ts

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,9 @@ import type {
44
AiChatMessageDocument,
55
ChatMessageDocument,
66
ChatState,
7-
UserSettings,
87
SystemPromptResult,
98
} from "@vibes.diy/prompts";
10-
import { DEFAULT_CODING_MODEL } from "@vibes.diy/prompts";
119

12-
import { useFireproof } from "use-fireproof";
13-
import { VibesDiyEnv } from "../config/env.js";
1410
import { saveErrorAsSystemMessage } from "./saveErrorAsSystemMessage.js";
1511
import { useApiKey } from "./useApiKey.js";
1612
import { useImmediateErrorAutoSend } from "./useImmediateErrorAutoSend.js";
@@ -24,6 +20,7 @@ import { useSystemPromptManager } from "./useSystemPromptManager.js";
2420
import { useThrottledUpdates } from "./useThrottledUpdates.js";
2521
import { RuntimeError } from "@vibes.diy/use-vibes-types";
2622
import { ErrorCategory, useRuntimeErrors } from "./useRuntimeErrors.js";
23+
import { useModelSelection } from "./useModelSelection.js";
2724

2825
// Constants
2926
const TITLE_MODEL = "meta-llama/llama-3.1-8b-instruct";
@@ -63,9 +60,6 @@ export function useSimpleChat(sessionId: string): ChatState {
6360
updateSelectedModel,
6461
} = useSession(sessionId);
6562

66-
// Get main database directly for settings document
67-
const { useDocument } = useFireproof(VibesDiyEnv.SETTINGS_DBNAME());
68-
6963
// Function to save errors as system messages to the session database
7064
const saveErrorAsSystemMessageCb = useCallback(
7165
(error: RuntimeError, category: ErrorCategory) =>
@@ -96,10 +90,8 @@ export function useSimpleChat(sessionId: string): ChatState {
9690
// Reference for input element
9791
const inputRef = useRef<HTMLTextAreaElement>(null);
9892

99-
// Get settings document
100-
const { doc: settingsDoc } = useDocument<UserSettings>({
101-
_id: "user_settings",
102-
});
93+
// Get model selection from shared hook
94+
const modelSelection = useModelSelection();
10395

10496
// State hooks
10597
const [isStreaming, setIsStreaming] = useState<boolean>(false);
@@ -113,7 +105,10 @@ export function useSimpleChat(sessionId: string): ChatState {
113105
const modelToUse = effectiveModel;
114106

115107
// Use our custom hooks
116-
const baseEnsureSystemPrompt = useSystemPromptManager(settingsDoc, vibeDoc);
108+
const baseEnsureSystemPrompt = useSystemPromptManager(
109+
modelSelection.settingsDoc,
110+
vibeDoc,
111+
);
117112

118113
// Create wrapper that handles dependency updates
119114
const ensureSystemPrompt = useCallback(
@@ -345,10 +340,9 @@ ${code}
345340
sessionId: session._id,
346341
vibeDoc,
347342
selectedModel: vibeDoc?.selectedModel,
348-
effectiveModel:
349-
effectiveModel[0] || settingsDoc?.model || DEFAULT_CODING_MODEL,
350-
globalModel: settingsDoc?.model,
351-
showModelPickerInChat: settingsDoc?.showModelPickerInChat || false,
343+
effectiveModel: effectiveModel[0] || modelSelection.effectiveModel,
344+
globalModel: modelSelection.globalModel,
345+
showModelPickerInChat: modelSelection.showModelPickerInChat,
352346
addScreenshot,
353347
docs: messages,
354348
setSelectedResponseId,

0 commit comments

Comments
 (0)