fixed /chat
This commit is contained in:
@@ -23,7 +23,7 @@ export const ChatPanelWrapper = () => {
|
||||
const sessionId = selection?.sessionId ?? undefined;
|
||||
const model = selection?.model ?? undefined;
|
||||
|
||||
const chat = usePiChat(sessionId, model, { replaceUrl: false });
|
||||
const chat = usePiChat(sessionId, model, { replaceUrl: false, projectScoped: scoped });
|
||||
|
||||
useEffect(() => {
|
||||
setActiveSession(chat.sessionId);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState } from 'react';
|
||||
import { useLocation } from 'react-router';
|
||||
import { useLocation, useNavigate } from 'react-router';
|
||||
import { Trash2, Home, Monitor } from 'lucide-react';
|
||||
import { usePanelChannel } from 'hooks/usePanelChannel';
|
||||
import { useAuth } from 'hooks/useAuth';
|
||||
@@ -66,6 +66,7 @@ type SessionChatProps = {
|
||||
};
|
||||
|
||||
function SessionChat({ sessionId, model }: SessionChatProps) {
|
||||
const navigate = useNavigate();
|
||||
const { sessions, deleteSession } = useChatSessions();
|
||||
const [, setSelected] = usePanelChannel<SelectedSession>(CHANNEL, null);
|
||||
const sessionTitle = sessions.find((s) => s.id === sessionId)?.title;
|
||||
@@ -81,7 +82,7 @@ function SessionChat({ sessionId, model }: SessionChatProps) {
|
||||
onDelete={async () => {
|
||||
await deleteSession(sessionId);
|
||||
setSelected(null);
|
||||
window.history.replaceState(null, '', '/chat');
|
||||
navigate('/chat', { replace: true });
|
||||
}}
|
||||
/>
|
||||
<EmbeddableChat
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useRef, useCallback, useState } from 'react';
|
||||
import { useNavigate } from 'react-router';
|
||||
import { Plus, MessageSquare, Folder, ChevronRight, FolderPlus } from 'lucide-react';
|
||||
import { usePanelChannel } from 'hooks/usePanelChannel';
|
||||
import { useChatSessions } from 'state/useChatSessions';
|
||||
@@ -10,6 +11,7 @@ import { GroupContextMenu } from './GroupContextMenu';
|
||||
import { SessionContextMenu } from './SessionContextMenu';
|
||||
|
||||
export const SessionList = () => {
|
||||
const navigate = useNavigate();
|
||||
const { sessions, deleteSession } = useChatSessions();
|
||||
const { groups } = useChatGroups();
|
||||
const [selected, setSelected] = usePanelChannel<SelectedSession>('chat:selected-session', null);
|
||||
@@ -47,13 +49,13 @@ export const SessionList = () => {
|
||||
|
||||
const handleSelect = (session: (typeof sessions)[number]) => {
|
||||
setSelected({ id: session.id, model: session.model ?? null });
|
||||
window.history.replaceState(null, '', `/chat/${session.id}`);
|
||||
navigate(`/chat/${session.id}`, { replace: true });
|
||||
};
|
||||
|
||||
const handleDelete = async (id: string) => {
|
||||
if (selected?.id === id) {
|
||||
setSelected(null);
|
||||
window.history.replaceState(null, '', '/chat');
|
||||
navigate('/chat', { replace: true });
|
||||
}
|
||||
await deleteSession(id);
|
||||
};
|
||||
@@ -133,7 +135,7 @@ export const SessionList = () => {
|
||||
<button
|
||||
onClick={() => {
|
||||
setSelected({ id: `new:${Date.now()}` });
|
||||
window.history.replaceState(null, '', '/chat/new');
|
||||
navigate('/chat/new', { replace: true });
|
||||
}}
|
||||
className="flex items-center gap-1.5 rounded-md bg-duck-teal hover:bg-duck-teal/90 text-duck-yellow cursor-pointer h-7 px-3 text-xs font-medium"
|
||||
>
|
||||
|
||||
@@ -16,10 +16,11 @@ type UsePiChatOptions = {
|
||||
storage?: ResourceChatStorage;
|
||||
resourceChatDir?: string;
|
||||
taskInfo?: TaskInfo;
|
||||
projectScoped?: boolean;
|
||||
};
|
||||
|
||||
export function usePiChat(initialSessionId?: string, initialModel?: string | null, options?: UsePiChatOptions) {
|
||||
const { replaceUrl = true, storage, resourceChatDir, taskInfo } = options ?? {};
|
||||
const { replaceUrl = true, storage, resourceChatDir, taskInfo, projectScoped } = options ?? {};
|
||||
const [messages, setMessages] = useState<ChatMessage[]>([]);
|
||||
const [streamingText, setStreamingText] = useState('');
|
||||
const [isGenerating, setIsGenerating] = useState(false);
|
||||
@@ -36,10 +37,11 @@ export function usePiChat(initialSessionId?: string, initialModel?: string | nul
|
||||
|
||||
// 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);
|
||||
if (!initialSessionId && !initialModel) {
|
||||
const defaultModel = (projectScoped && settings?.chat?.defaultProjectModel) || settings?.chat?.defaultModel;
|
||||
if (defaultModel) setSelectedModel(defaultModel);
|
||||
}
|
||||
}, [initialSessionId, initialModel, settings]);
|
||||
}, [initialSessionId, initialModel, settings, projectScoped]);
|
||||
|
||||
// Sync selectedModel when initialModel changes (e.g. resuming a session)
|
||||
useEffect(() => {
|
||||
|
||||
@@ -31,23 +31,15 @@ export function usePiModels() {
|
||||
enabled: isAuthenticated,
|
||||
queryFn: async () => {
|
||||
const data = await client.get<{ models: ModelOption[]; providerNames?: Record<string, string>; hostHome?: string }>('/pi/models');
|
||||
|
||||
console.log('[usePiModels] Fetched models:', {
|
||||
modelCount: data.models.length,
|
||||
providerNames: data.providerNames,
|
||||
providers: [...new Set(data.models.map((m: ModelOption) => m.provider))]
|
||||
});
|
||||
|
||||
// Store provider names for later use
|
||||
|
||||
if (data.providerNames) {
|
||||
globalProviderNames = data.providerNames;
|
||||
console.log('[usePiModels] Stored provider names:', globalProviderNames);
|
||||
}
|
||||
|
||||
if (data.hostHome) {
|
||||
globalHostHome = data.hostHome;
|
||||
}
|
||||
|
||||
|
||||
return data.models;
|
||||
},
|
||||
staleTime: 5 * 60 * 1000,
|
||||
@@ -86,3 +78,23 @@ export function useVisiblePiModels() {
|
||||
return isExplicitlyEnabled || isFromNewProvider;
|
||||
});
|
||||
}
|
||||
|
||||
/** Strict filtering — only explicitly enabled models, no "new provider" passthrough. */
|
||||
export function useEnabledPiModels() {
|
||||
const models = usePiModels();
|
||||
const { settings } = useSettings();
|
||||
const enabled = settings.ai?.enabledModels ?? [];
|
||||
const disabledProviders = new Set(settings.ai?.disabledProviders ?? []);
|
||||
|
||||
const providerFiltered = disabledProviders.size > 0
|
||||
? models.filter((m) => !disabledProviders.has(m.provider))
|
||||
: models;
|
||||
|
||||
if (enabled.length === 0) return providerFiltered;
|
||||
|
||||
// Match by modelKey (new format), model id, or model name (legacy formats)
|
||||
const enabledSet = new Set(enabled);
|
||||
return providerFiltered.filter((m) =>
|
||||
enabledSet.has(modelKey(m)) || enabledSet.has(m.id) || enabledSet.has(m.name),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ export type UserSettings = {
|
||||
chat: {
|
||||
defaultProvider: 'pi';
|
||||
defaultModel: string | null;
|
||||
defaultProjectModel: string | null;
|
||||
systemPrompt: string;
|
||||
temperature: number;
|
||||
defaultPwd: string;
|
||||
@@ -79,6 +80,7 @@ export const DEFAULT_SETTINGS: UserSettings = {
|
||||
chat: {
|
||||
defaultProvider: 'pi',
|
||||
defaultModel: null,
|
||||
defaultProjectModel: null,
|
||||
systemPrompt: '',
|
||||
temperature: 1,
|
||||
defaultPwd: '~',
|
||||
|
||||
Reference in New Issue
Block a user