perf(app): reduce startup websocket work

Make provider catalogs compact and content-addressed so repeat launches can reuse the persisted snapshot instead of transferring it again. Remove eager global catalog loading and the stopped-agent defensive tail fetch, while keeping sequence-gap and reconnect recovery as the correctness paths. Add an opt-in production-ID Android profiling build for local startup traces.
This commit is contained in:
Mohamed Boudra
2026-08-04 15:45:55 +02:00
parent 8e5b6876b4
commit 7dbeff8290
36 changed files with 1209 additions and 171 deletions
+1
View File
@@ -841,6 +841,7 @@ export class Session {
emit: (msg) => this.emit(msg),
isProviderVisibleToClient: (provider) => this.isProviderVisibleToClient(provider),
supportsCustomModeIcons: () => this.supports(CLIENT_CAPS.customModeIcons),
supportsCompactProviderSnapshots: () => this.supports(CLIENT_CAPS.compactProviderSnapshots),
listProviderAvailability: () => this.agentManager.listProviderAvailability(),
listDraftFeatures: (config) => this.agentManager.listDraftFeatures(config),
},
@@ -13,12 +13,14 @@ import {
} from "../../agent/provider-snapshot-manager.js";
import type { ProviderSnapshotEntry } from "../../agent/agent-sdk-types.js";
import type { ProviderUsageService } from "../../../services/quota-fetcher/service.js";
import { expandProviderSnapshot } from "@getpaseo/protocol/provider-snapshot-codec";
type SnapshotChangeHandler = (entries: ProviderSnapshotEntry[], cwd: string) => void;
interface MakeOptions {
visibleProviders?: Set<string>;
supportsCustomModeIcons?: boolean;
supportsCompactProviderSnapshots?: boolean;
snapshot?: { [K in keyof ProviderSnapshotManager]?: unknown };
usage?: { [K in keyof ProviderUsageService]?: unknown };
host?: Partial<ProviderCatalogSessionHost>;
@@ -49,6 +51,7 @@ function makeSubsystem(options: MakeOptions = {}) {
emit: (msg) => emitted.push(msg),
isProviderVisibleToClient: (provider) => visible.has(provider),
supportsCustomModeIcons: () => options.supportsCustomModeIcons ?? false,
supportsCompactProviderSnapshots: () => options.supportsCompactProviderSnapshots ?? false,
listProviderAvailability: async () => [],
listDraftFeatures: async () => [],
...options.host,
@@ -113,6 +116,21 @@ describe("ProviderCatalogSession", () => {
expect(pull?.payload.entries).toEqual(push?.payload.entries);
});
it("pushes the compact encoding to capable clients", () => {
const { subsystem, emitted, pushSnapshotChange } = makeSubsystem({
supportsCustomModeIcons: true,
supportsCompactProviderSnapshots: true,
});
subsystem.start();
pushSnapshotChange(makeEntries());
const push = findByType(emitted, "providers_snapshot_update");
expect(push?.payload.entries).toEqual([]);
expect(push?.payload.snapshotHash).toEqual(expect.any(String));
expect(expandProviderSnapshot(push!.payload.compactSnapshot!)).toEqual([makeEntries()[0]]);
});
it("preserves custom mode icons when the client supports them", async () => {
const { subsystem, emitted } = makeSubsystem({
supportsCustomModeIcons: true,
@@ -128,6 +146,60 @@ describe("ProviderCatalogSession", () => {
expect(pull?.payload.entries[0]?.modes?.[0]?.icon).toBe("Sparkles");
});
it("sends capable clients a compact snapshot and returns not-modified for its hash", async () => {
const thinkingOptions = [
{ id: "low", label: "Low" },
{ id: "high", label: "High", isDefault: true },
];
const entries: ProviderSnapshotEntry[] = [
{
provider: "codex",
status: "ready",
enabled: true,
models: ["one", "two"].map((id) => ({
provider: "codex",
id,
label: id,
thinkingOptions,
defaultThinkingOptionId: "high",
})),
},
];
const { subsystem, emitted } = makeSubsystem({
supportsCompactProviderSnapshots: true,
snapshot: { getSnapshot: () => entries },
});
await subsystem.handleGetProvidersSnapshotRequest({
type: "get_providers_snapshot_request",
requestId: "compact-1",
});
const first = findByType(emitted, "get_providers_snapshot_response");
expect(first?.payload.entries).toEqual([]);
expect(first?.payload.snapshotHash).toEqual(expect.any(String));
expect(first?.payload.compactSnapshot?.thinkingSets).toHaveLength(1);
expect(expandProviderSnapshot(first!.payload.compactSnapshot!)).toEqual(entries);
await subsystem.handleGetProvidersSnapshotRequest({
type: "get_providers_snapshot_request",
requestId: "compact-2",
ifNoneMatch: first?.payload.snapshotHash,
});
const responses = emitted.filter(
(message) => message.type === "get_providers_snapshot_response",
);
const second = responses[1];
expect(second?.payload).toMatchObject({
entries: [],
snapshotHash: first?.payload.snapshotHash,
notModified: true,
requestId: "compact-2",
});
expect(second?.payload.compactSnapshot).toBeUndefined();
});
it("reports a disabled provider on list_provider_models without warming the snapshot", async () => {
// warmUpSnapshotForCwd is intentionally unstubbed: createStub throws if it is called,
// so the disabled short-circuit is proven by the absence of a throw.
@@ -1,5 +1,10 @@
import type pino from "pino";
import { createHash } from "node:crypto";
import { getErrorMessage } from "@getpaseo/protocol/error-utils";
import {
compactProviderSnapshot,
type CompactProviderSnapshot,
} from "@getpaseo/protocol/provider-snapshot-codec";
import type { SessionInboundMessage, SessionOutboundMessage } from "../../messages.js";
import {
isGlobalProviderSnapshotKey,
@@ -39,6 +44,7 @@ export interface ProviderCatalogSessionHost {
isProviderVisibleToClient(provider: string): boolean;
// COMPAT(customModeIcons): reads clientCapabilities live.
supportsCustomModeIcons(): boolean;
supportsCompactProviderSnapshots(): boolean;
listProviderAvailability(): Promise<ProviderAvailability[]>;
listDraftFeatures(config: AgentSessionConfig): Promise<AgentFeature[]>;
}
@@ -50,6 +56,19 @@ export interface ProviderCatalogSessionOptions {
logger: pino.Logger;
}
interface EncodedProviderSnapshot {
compactSnapshot: CompactProviderSnapshot;
snapshotHash: string;
}
function encodeProviderSnapshot(entries: ProviderSnapshotEntry[]): EncodedProviderSnapshot {
const compactSnapshot = compactProviderSnapshot(entries);
const snapshotHash = createHash("sha256")
.update(JSON.stringify(compactSnapshot))
.digest("base64url");
return { compactSnapshot, snapshotHash };
}
/**
* A client's provider catalog surface: model / mode / feature listing, the providers
* snapshot push + pull, provider diagnostics, and usage. The snapshot PUSH (start) and
@@ -78,11 +97,25 @@ export class ProviderCatalogSession {
this.host.isProviderVisibleToClient(entry.provider),
);
const snapshotCwd = isGlobalProviderSnapshotKey(cwd) ? undefined : cwd;
const clientEntries = this.downgradeEntryModesForClient(visibleEntries);
if (this.host.supportsCompactProviderSnapshots()) {
const encoded = encodeProviderSnapshot(clientEntries);
this.host.emit({
type: "providers_snapshot_update",
payload: {
...(snapshotCwd ? { cwd: snapshotCwd } : {}),
entries: [],
...encoded,
generatedAt: new Date().toISOString(),
},
});
return;
}
this.host.emit({
type: "providers_snapshot_update",
payload: {
...(snapshotCwd ? { cwd: snapshotCwd } : {}),
entries: this.downgradeEntryModesForClient(visibleEntries),
entries: clientEntries,
generatedAt: new Date().toISOString(),
},
});
@@ -360,11 +393,29 @@ export class ProviderCatalogSession {
const entries = this.providerSnapshotManager
.getSnapshot(msg.cwd ? expandTilde(msg.cwd) : undefined)
.filter((entry) => this.host.isProviderVisibleToClient(entry.provider));
const clientEntries = this.downgradeEntryModesForClient(entries);
if (this.host.supportsCompactProviderSnapshots()) {
const encoded = encodeProviderSnapshot(clientEntries);
const notModified = msg.ifNoneMatch === encoded.snapshotHash;
this.host.emit({
type: "get_providers_snapshot_response",
payload: {
entries: [],
...(!notModified ? { compactSnapshot: encoded.compactSnapshot } : {}),
snapshotHash: encoded.snapshotHash,
...(notModified ? { notModified: true } : {}),
generatedAt: new Date().toISOString(),
requestId: msg.requestId,
},
});
return;
}
this.host.emit({
type: "get_providers_snapshot_response",
payload: {
entries: this.downgradeEntryModesForClient(entries),
entries: clientEntries,
generatedAt: new Date().toISOString(),
requestId: msg.requestId,
},