feat(app): provider system overhaul with model selector, diagnostics, and UX polish
- Add CombinedModelSelector with two-level drill-down (providers → models), favorites section, search, and single-provider auto-drill mode - Add provider snapshot system (ProviderSnapshotManager) for cached provider/model state - Add provider diagnostics with resolved binary paths and versions across all providers - Add StatusBadge shared component for consistent status visual language - Add ProviderDiagnosticSheet for detailed provider health inspection - Add desktop auto-focus on input after any status bar interaction (model, mode, thinking, features) using focusWithRetries - Fix Combobox flicker on height change by switching to bottom-based CSS positioning once initial floating-ui position resolves - Add dynamic dropdown height: Level 1 fits content, Level 2 calculates from model count - Remove "Other providers" section from model selector (only show available providers)
This commit is contained in:
@@ -43,6 +43,9 @@ import type {
|
||||
ListAvailableProvidersResponse,
|
||||
ListTerminalsResponse,
|
||||
CreateTerminalResponse,
|
||||
GetProvidersSnapshotResponseMessage,
|
||||
ProviderDiagnosticResponseMessage,
|
||||
RefreshProvidersSnapshotResponseMessage,
|
||||
SubscribeTerminalResponse,
|
||||
TerminalState,
|
||||
CloseItemsResponse,
|
||||
@@ -147,6 +150,10 @@ export type DaemonEvent =
|
||||
requestId: string;
|
||||
resolution: AgentPermissionResponse;
|
||||
}
|
||||
| {
|
||||
type: "providers_snapshot_update";
|
||||
payload: Extract<SessionOutboundMessage, { type: "providers_snapshot_update" }>["payload"];
|
||||
}
|
||||
| { type: "error"; message: string };
|
||||
|
||||
export type DaemonEventHandler = (event: DaemonEvent) => void;
|
||||
@@ -222,6 +229,9 @@ type ListProviderFeaturesPayload = ListProviderFeaturesResponseMessage["payload"
|
||||
type ListProviderModelsPayload = ListProviderModelsResponseMessage["payload"];
|
||||
type ListProviderModesPayload = ListProviderModesResponseMessage["payload"];
|
||||
type ListAvailableProvidersPayload = ListAvailableProvidersResponse["payload"];
|
||||
type GetProvidersSnapshotPayload = GetProvidersSnapshotResponseMessage["payload"];
|
||||
type RefreshProvidersSnapshotPayload = RefreshProvidersSnapshotResponseMessage["payload"];
|
||||
type ProviderDiagnosticPayload = ProviderDiagnosticResponseMessage["payload"];
|
||||
type ListCommandsPayload = ListCommandsResponse["payload"];
|
||||
type ListCommandsDraftConfig = Pick<
|
||||
AgentSessionConfig,
|
||||
@@ -2552,6 +2562,51 @@ export class DaemonClient {
|
||||
});
|
||||
}
|
||||
|
||||
async getProvidersSnapshot(options?: {
|
||||
cwd?: string;
|
||||
requestId?: string;
|
||||
}): Promise<GetProvidersSnapshotPayload> {
|
||||
return this.sendCorrelatedSessionRequest({
|
||||
requestId: options?.requestId,
|
||||
message: {
|
||||
type: "get_providers_snapshot_request",
|
||||
cwd: options?.cwd,
|
||||
},
|
||||
responseType: "get_providers_snapshot_response",
|
||||
timeout: 10000,
|
||||
});
|
||||
}
|
||||
|
||||
async refreshProvidersSnapshot(options?: {
|
||||
cwd?: string;
|
||||
requestId?: string;
|
||||
}): Promise<RefreshProvidersSnapshotPayload> {
|
||||
return this.sendCorrelatedSessionRequest({
|
||||
requestId: options?.requestId,
|
||||
message: {
|
||||
type: "refresh_providers_snapshot_request",
|
||||
cwd: options?.cwd,
|
||||
},
|
||||
responseType: "refresh_providers_snapshot_response",
|
||||
timeout: 5000,
|
||||
});
|
||||
}
|
||||
|
||||
async getProviderDiagnostic(
|
||||
provider: AgentProvider,
|
||||
options?: { requestId?: string },
|
||||
): Promise<ProviderDiagnosticPayload> {
|
||||
return this.sendCorrelatedSessionRequest({
|
||||
requestId: options?.requestId,
|
||||
message: {
|
||||
type: "provider_diagnostic_request",
|
||||
provider,
|
||||
},
|
||||
responseType: "provider_diagnostic_response",
|
||||
timeout: 30000,
|
||||
});
|
||||
}
|
||||
|
||||
async listCommands(agentId: string, requestId?: string): Promise<ListCommandsPayload>;
|
||||
async listCommands(agentId: string, options?: ListCommandsOptions): Promise<ListCommandsPayload>;
|
||||
async listCommands(
|
||||
@@ -3637,6 +3692,11 @@ export class DaemonClient {
|
||||
requestId: msg.payload.requestId,
|
||||
resolution: msg.payload.resolution,
|
||||
};
|
||||
case "providers_snapshot_update":
|
||||
return {
|
||||
type: "providers_snapshot_update",
|
||||
payload: msg.payload,
|
||||
};
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user