diff --git a/packages/app/src/hooks/use-provider-models.ts b/packages/app/src/hooks/use-provider-models.ts deleted file mode 100644 index 25e861e79..000000000 --- a/packages/app/src/hooks/use-provider-models.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { useMemo } from "react"; -import { useQueries } from "@tanstack/react-query"; -import { - AGENT_PROVIDER_DEFINITIONS, - type AgentProviderDefinition, -} from "@server/server/agent/provider-manifest"; -import type { AgentModelDefinition, AgentProvider } from "@server/server/agent/agent-sdk-types"; -import { useHostRuntimeClient, useHostRuntimeIsConnected } from "@/runtime/host-runtime"; - -const STALE_TIME = 5 * 60 * 1000; - -export function useProviderModels(serverId: string) { - const client = useHostRuntimeClient(serverId); - const isConnected = useHostRuntimeIsConnected(serverId); - const enabled = Boolean(serverId && client && isConnected); - - const queries = useQueries({ - queries: AGENT_PROVIDER_DEFINITIONS.map((def) => ({ - queryKey: ["providerModels", serverId, def.id] as const, - enabled, - staleTime: STALE_TIME, - queryFn: async () => { - if (!client) { - throw new Error("Host is not connected"); - } - const payload = await client.listProviderModels(def.id as AgentProvider); - if (payload.error) { - throw new Error(payload.error); - } - return payload.models ?? []; - }, - })), - }); - - const allProviderModels = useMemo(() => { - const map = new Map(); - for (let i = 0; i < AGENT_PROVIDER_DEFINITIONS.length; i++) { - const query = queries[i]; - if (query?.data) { - map.set(AGENT_PROVIDER_DEFINITIONS[i]!.id, query.data); - } - } - return map; - }, [queries]); - - const isLoading = queries.some((q) => q.isLoading); - - return { allProviderModels, isLoading }; -} diff --git a/packages/app/src/screens/workspace/workspace-screen.tsx b/packages/app/src/screens/workspace/workspace-screen.tsx index 302136e68..087a99e38 100644 --- a/packages/app/src/screens/workspace/workspace-screen.tsx +++ b/packages/app/src/screens/workspace/workspace-screen.tsx @@ -64,7 +64,7 @@ import { workspaceTabTargetsEqual, } from "@/utils/workspace-tab-identity"; import { useHostRuntimeClient, useHostRuntimeIsConnected } from "@/runtime/host-runtime"; -import { useProviderModels } from "@/hooks/use-provider-models"; +import { useProvidersSnapshot } from "@/hooks/use-providers-snapshot"; import { useWorkspaceSetupStore } from "@/stores/workspace-setup-store"; import { useWorkspaceTerminalSessionRetention } from "@/terminal/hooks/use-workspace-terminal-session-retention"; import { @@ -612,9 +612,6 @@ function WorkspaceScreenContent({ serverId, workspaceId }: WorkspaceScreenProps) const normalizedServerId = trimNonEmpty(decodeSegment(serverId)) ?? ""; - // Prefetch provider models early so the model picker is warm by the time it opens - useProviderModels(normalizedServerId); - const normalizedWorkspaceId = resolveWorkspaceRouteId({ routeWorkspaceId: workspaceId, @@ -645,6 +642,10 @@ function WorkspaceScreenContent({ serverId, workspaceId }: WorkspaceScreenProps) ); const workspaceDirectory = workspaceAuthority?.workspaceDirectory ?? null; const isMissingWorkspaceExecutionAuthority = Boolean(workspaceDescriptor && !workspaceAuthority); + + // Warm the server-side provider snapshot for this workspace cwd so the model + // picker is ready when opened. Consumers share the same query cache key. + useProvidersSnapshot(normalizedServerId, workspaceDirectory); const [pendingTerminalCreateInput, setPendingTerminalCreateInput] = useState<{ paneId?: string; } | null>(null);