perf: speed up model/agent readiness on the initial draft

Load startup config under the owning project's directory key (resolving from a
worktree directory when needed) so the auto-opened draft, which activates the
project, finds a ready providers/agents snapshot instead of triggering a second
load. Also dedupe app.agents: listAgents now takes the directory directly and
shares an in-flight request, so the config store and agents store no longer
issue duplicate agent fetches at startup.
This commit is contained in:
Bohdan Triapitsyn
2026-06-14 22:04:32 +03:00
parent 9111611bdc
commit 296177357b
4 changed files with 56 additions and 12 deletions
+4 -2
View File
@@ -245,8 +245,10 @@ export const useAgentsStore = create<AgentsStore>()(
try {
const queryParams = configDirectory ? `?directory=${encodeURIComponent(configDirectory)}` : '';
// Ensure we list agents using the correct project context
const agents = await opencodeClient.withDirectory(configDirectory, () => opencodeClient.listAgents());
// Ensure we list agents using the correct project context. Pass the
// directory directly so this shares the in-flight request with the config
// store instead of issuing a duplicate agents fetch at startup.
const agents = await opencodeClient.listAgents(configDirectory);
const agentsWithScope = await Promise.all(
agents.map(async (agent) => {
+23 -3
View File
@@ -12,6 +12,8 @@ import { useSelectionStore } from "@/sync/selection-store";
import { getRegisteredRuntimeAPIs } from "@/contexts/runtimeAPIRegistry";
import { updateDesktopSettings } from "@/lib/persistence";
import { useDirectoryStore } from "@/stores/useDirectoryStore";
import { useProjectsStore } from "@/stores/useProjectsStore";
import { resolveProjectForSessionDirectory } from "@/lib/projectResolution";
import { streamDebugEnabled } from "@/stores/utils/streamDebug";
import { parseModelIdentifier } from "@/lib/modelIdentifier";
import { runtimeFetch } from "@/lib/runtime-fetch";
@@ -1710,7 +1712,7 @@ export const useConfigStore = create<ConfigStore>()(
const [agents, openChamberDefaults, opencodeConfig] = await Promise.all([
measureStartupTrace(
'loadAgents:api',
() => opencodeClient.withDirectory(fromDirectoryKey(directoryKey), () => opencodeClient.listAgents()),
() => opencodeClient.listAgents(fromDirectoryKey(directoryKey)),
{ directoryKey, source, requestedDirectory, effectiveDirectory, attempt: attempt + 1 },
),
fetchOpenChamberDefaults(),
@@ -2634,10 +2636,28 @@ export const useConfigStore = create<ConfigStore>()(
get().invalidateProviderCache();
// Config (providers/agents/defaults) lives at the PROJECT level. If the
// app starts on a worktree directory, load config under the owning
// project's key so the initial draft — which activates the project — finds
// a ready snapshot instead of triggering a second provider/agent load.
const initialDirectory = opencodeClient.getDirectory()
?? useDirectoryStore.getState().currentDirectory
?? fromDirectoryKey(get().activeDirectoryKey);
const resolvedProject = resolveProjectForSessionDirectory(
useProjectsStore.getState().projects,
useSessionUIStore.getState().availableWorktreesByProject,
initialDirectory ?? null,
);
const configDirectory = resolvedProject?.path ?? initialDirectory ?? null;
const configDirectoryKey = toDirectoryKey(configDirectory);
if (get().activeDirectoryKey !== configDirectoryKey) {
set({ activeDirectoryKey: configDirectoryKey });
}
if (debug) console.log("Loading providers and agents...");
await Promise.all([
get().loadProviders({ source: 'initializeApp' }),
get().loadAgents({ source: 'initializeApp' }),
get().loadProviders({ directory: configDirectory, source: 'initializeApp' }),
get().loadAgents({ directory: configDirectory, source: 'initializeApp' }),
]);
set({ isInitialized: true, isConnected: true, hasEverConnected: true, connectionPhase: "connected" });