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:
@@ -229,6 +229,7 @@ class OpencodeService {
|
||||
private currentDirectory: string | undefined = undefined;
|
||||
private directoryContextQueue: Promise<void> = Promise.resolve();
|
||||
private listDirectoryInFlight: Map<string, Promise<FilesystemEntry[]>> = new Map();
|
||||
private listAgentsInFlight: Map<string, Promise<Agent[]>> = new Map();
|
||||
private listDirectoryCache: Map<string, { entries: FilesystemEntry[]; expiresAt: number }> = new Map();
|
||||
|
||||
constructor(baseUrl: string = DEFAULT_BASE_URL) {
|
||||
@@ -1294,14 +1295,34 @@ class OpencodeService {
|
||||
* useAgentsStore) can observe failure and retry; silently returning an
|
||||
* empty list would defeat retries and clear the cached agent list.
|
||||
*/
|
||||
async listAgents(): Promise<Agent[]> {
|
||||
const response = await this.client.app.agents(
|
||||
this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
||||
);
|
||||
if (response.error) {
|
||||
throw new Error(`app.agents failed: ${formatSdkError(response.error)}`);
|
||||
async listAgents(directory?: string | null): Promise<Agent[]> {
|
||||
// Pass the directory explicitly so we don't depend on (and serialize behind)
|
||||
// withDirectory's shared context queue. Concurrent callers for the same
|
||||
// directory (e.g. config store + agents store at startup) share one request.
|
||||
const effectiveDirectory = this.normalizeCandidatePath(directory) ?? directory ?? this.currentDirectory ?? undefined;
|
||||
const key = effectiveDirectory ?? '';
|
||||
|
||||
const existing = this.listAgentsInFlight.get(key);
|
||||
if (existing) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
const request = (async () => {
|
||||
const response = await this.client.app.agents(
|
||||
effectiveDirectory ? { directory: effectiveDirectory } : undefined
|
||||
);
|
||||
if (response.error) {
|
||||
throw new Error(`app.agents failed: ${formatSdkError(response.error)}`);
|
||||
}
|
||||
return response.data || [];
|
||||
})();
|
||||
|
||||
this.listAgentsInFlight.set(key, request);
|
||||
try {
|
||||
return await request;
|
||||
} finally {
|
||||
this.listAgentsInFlight.delete(key);
|
||||
}
|
||||
return response.data || [];
|
||||
}
|
||||
|
||||
// SSE infrastructure removed — EventPipeline in sync/event-pipeline.ts handles
|
||||
|
||||
Reference in New Issue
Block a user