default model
This commit is contained in:
@@ -112,6 +112,7 @@ export function ChatLauncher({
|
||||
model={selectedModel}
|
||||
isConnected={true}
|
||||
isGenerating={false}
|
||||
hasStarted={false}
|
||||
/>
|
||||
|
||||
<WebpageDialog open={urlDialogOpen} onOpenChange={setUrlDialogOpen} onSubmit={attachWebpage} />
|
||||
|
||||
@@ -35,6 +35,7 @@ export function useEmbeddableChat(params: UseEmbeddableChatParams) {
|
||||
sessionId,
|
||||
model,
|
||||
selectedModel,
|
||||
hasStarted,
|
||||
setSelectedModel,
|
||||
sendPrompt,
|
||||
stopGeneration,
|
||||
@@ -170,6 +171,7 @@ export function useEmbeddableChat(params: UseEmbeddableChatParams) {
|
||||
sessionId,
|
||||
model,
|
||||
selectedModel,
|
||||
hasStarted,
|
||||
setSelectedModel,
|
||||
sendPrompt,
|
||||
stopGeneration,
|
||||
|
||||
@@ -28,6 +28,7 @@ export const InputArea = ({ manager }: InputAreaProps) => {
|
||||
selectedModel,
|
||||
setSelectedModel,
|
||||
model,
|
||||
hasStarted,
|
||||
attachments,
|
||||
attachWebpage,
|
||||
attachImage,
|
||||
@@ -94,6 +95,7 @@ export const InputArea = ({ manager }: InputAreaProps) => {
|
||||
model={model}
|
||||
isConnected={isConnected}
|
||||
isGenerating={isGenerating}
|
||||
hasStarted={hasStarted}
|
||||
/>
|
||||
|
||||
<WebpageDialog open={urlDialogOpen} onOpenChange={setUrlDialogOpen} onSubmit={attachWebpage} />
|
||||
|
||||
@@ -27,6 +27,7 @@ type ModelSelectorProps = {
|
||||
model: string | null;
|
||||
isConnected: boolean;
|
||||
isGenerating: boolean;
|
||||
hasStarted: boolean;
|
||||
};
|
||||
|
||||
export function ModelSelector({
|
||||
@@ -37,23 +38,40 @@ export function ModelSelector({
|
||||
model,
|
||||
isConnected,
|
||||
isGenerating,
|
||||
hasStarted,
|
||||
}: ModelSelectorProps) {
|
||||
const providers = [...new Set(availableModels.map((m) => m.provider).filter(Boolean))] as string[];
|
||||
|
||||
const activeProvider = availableModels.find((m) => m.id === selectedModel)?.provider ?? providers[0];
|
||||
// Determine which model to display: selectedModel takes precedence, then model (from server), then fallback
|
||||
const displayModel = selectedModel || model;
|
||||
|
||||
const activeProvider = availableModels.find((m) => m.id === displayModel)?.provider ?? providers[0];
|
||||
const providerModels = availableModels.filter((m) => m.provider === activeProvider);
|
||||
const fallbackModelId = providerModels[0]?.id ?? null;
|
||||
|
||||
// Lock after session has started
|
||||
const isLocked = hasStarted || isGenerating || !isConnected;
|
||||
|
||||
const handleProviderClick = (provider: string) => {
|
||||
if (isLocked) return;
|
||||
const firstModel = availableModels.find((m) => m.provider === provider);
|
||||
if (firstModel) onModelChange(firstModel.id);
|
||||
};
|
||||
|
||||
const displayName = (provider: string) => PROVIDER_DISPLAY[provider] ?? provider;
|
||||
|
||||
// Get display text for the model
|
||||
const getModelDisplayText = () => {
|
||||
if (displayModel) {
|
||||
const found = availableModels.find((m) => m.id === displayModel);
|
||||
return found?.name || displayModel;
|
||||
}
|
||||
return 'Select model';
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-between mt-2">
|
||||
{messages.length > 0 ? (
|
||||
{isLocked ? (
|
||||
<span className="rounded-md bg-duck-dark/80 px-3 py-1 text-xs font-medium text-white">
|
||||
{activeProvider ? displayName(activeProvider) : 'Pi'}
|
||||
</span>
|
||||
@@ -77,9 +95,9 @@ export function ModelSelector({
|
||||
<div className="text-xs text-duck-dark/50">
|
||||
{providerModels.length > 0 ? (
|
||||
<Select
|
||||
value={selectedModel ?? fallbackModelId ?? undefined}
|
||||
onValueChange={(v) => onModelChange(v)}
|
||||
disabled={isGenerating || !isConnected}
|
||||
value={displayModel ?? fallbackModelId ?? undefined}
|
||||
onValueChange={(v) => !isLocked && onModelChange(v)}
|
||||
disabled={isLocked}
|
||||
>
|
||||
<SelectTrigger className="h-auto border-0 bg-transparent p-0 text-xs text-duck-dark/50 shadow-none focus:ring-0 gap-1 cursor-pointer">
|
||||
<SelectValue />
|
||||
@@ -93,7 +111,7 @@ export function ModelSelector({
|
||||
</SelectContent>
|
||||
</Select>
|
||||
) : (
|
||||
<span>{model ?? 'Pi'}</span>
|
||||
<span>{getModelDisplayText()}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { useChatWebSocket } from 'hooks/useChatWebSocket';
|
||||
import { useChatSessions } from 'state/useChatSessions';
|
||||
import { useSettings } from 'state/useSettings';
|
||||
import type { ChatMessage, ServerMessage, TaskInfo, Message } from '../apps/Chat/types';
|
||||
|
||||
const SAVE_DEBOUNCE_MS = 1000;
|
||||
@@ -27,6 +28,19 @@ export function usePiChat(initialSessionId?: string, initialModel?: string | nul
|
||||
const [selectedModel, setSelectedModel] = useState<string | null>(initialModel ?? null);
|
||||
const [cwd, setCwd] = useState<string | null>(null);
|
||||
|
||||
// Track if session has started (first message sent)
|
||||
const [hasStarted, setHasStarted] = useState(false);
|
||||
|
||||
// Get user settings for default model
|
||||
const { settings } = useSettings();
|
||||
|
||||
// Set default model from settings when starting a new chat (no initialSessionId, no initialModel)
|
||||
useEffect(() => {
|
||||
if (!initialSessionId && !initialModel && settings?.chat?.defaultModel) {
|
||||
setSelectedModel(settings.chat.defaultModel);
|
||||
}
|
||||
}, [initialSessionId, initialModel, settings]);
|
||||
|
||||
const streamingRef = useRef('');
|
||||
const rafRef = useRef<number | null>(null);
|
||||
const sessionIdRef = useRef<string | null>(initialSessionId ?? null);
|
||||
@@ -238,6 +252,11 @@ export function usePiChat(initialSessionId?: string, initialModel?: string | nul
|
||||
cwdParam?: { root?: string; path: string },
|
||||
groupSlug?: string | null,
|
||||
) {
|
||||
// Mark session as started on first message
|
||||
if (!hasStarted) {
|
||||
setHasStarted(true);
|
||||
}
|
||||
|
||||
setMessages((prev) => [...prev, { role: 'user', text, ...(images?.length ? { images } : {}) }]);
|
||||
setIsGenerating(true);
|
||||
streamingRef.current = '';
|
||||
@@ -277,6 +296,7 @@ export function usePiChat(initialSessionId?: string, initialModel?: string | nul
|
||||
sessionId,
|
||||
model,
|
||||
selectedModel,
|
||||
hasStarted,
|
||||
cwd,
|
||||
setSelectedModel,
|
||||
sendPrompt,
|
||||
|
||||
Reference in New Issue
Block a user