Rework provider selector and settings UX
Surface all enabled providers in the model selector with inline loading and error states instead of silently hiding non-ready ones. Tap any row to drill in; loading and error states show in the drill-down body, with a Retry button on error. Providers with no models render a synthetic "Default" row so every provider's drill-down has symmetric structure. Redesign the per-provider settings sheet: search lives in the header, discovered and custom models share one scrolling list, and the footer hosts action buttons. Diagnostic and "Add model" each open as their own sub-sheet, so neither expands inline or shifts the surrounding layout. Snapshot refresh now keeps cached data visible: setQueryData replaces the cache atomically and sibling-scope caches are invalidated (not removed), so refreshing a provider no longer blanks its row. Search inputs across the app are uncontrolled — onChangeText drives parent state, and resetKey remounts the field when an explicit reset is needed — to avoid RN's controlled-input flicker. Adds a dev-only mock-slow provider whose discovery never resolves, so the 30s snapshot timeout produces a real error and lets loading and timeout-error UI be exercised end to end.
This commit is contained in:
@@ -151,6 +151,16 @@ const MOCK_LOAD_TEST_MODES: AgentProviderModeDefinition[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const MOCK_SLOW_MODES: AgentProviderModeDefinition[] = [
|
||||
{
|
||||
id: "default",
|
||||
label: "Default",
|
||||
description: "Dev-only mode for the mock slow provider",
|
||||
icon: "ShieldOff",
|
||||
colorTier: "dangerous",
|
||||
},
|
||||
];
|
||||
|
||||
export const AGENT_PROVIDER_DEFINITIONS: AgentProviderDefinition[] = [
|
||||
{
|
||||
id: "claude",
|
||||
@@ -212,6 +222,13 @@ export const DEV_AGENT_PROVIDER_DEFINITIONS: AgentProviderDefinition[] = [
|
||||
defaultModeId: "load-test",
|
||||
modes: MOCK_LOAD_TEST_MODES,
|
||||
},
|
||||
{
|
||||
id: "mock-slow",
|
||||
label: "Mock Slow Provider",
|
||||
description: "Dev-only: hangs during model discovery to test loading and timeout UI",
|
||||
defaultModeId: "default",
|
||||
modes: MOCK_SLOW_MODES,
|
||||
},
|
||||
];
|
||||
|
||||
export function getAgentProviderDefinition(
|
||||
|
||||
@@ -31,6 +31,7 @@ import { OpenCodeAgentClient } from "./providers/opencode-agent.js";
|
||||
import { OpenCodeServerManager } from "./providers/opencode/server-manager.js";
|
||||
import { PiRpcAgentClient } from "./providers/pi/agent.js";
|
||||
import { MockLoadTestAgentClient } from "./providers/mock-load-test-agent.js";
|
||||
import { MockSlowProviderClient } from "./providers/mock-slow-provider.js";
|
||||
import {
|
||||
AGENT_PROVIDER_DEFINITIONS,
|
||||
BUILTIN_PROVIDER_IDS,
|
||||
@@ -126,6 +127,7 @@ const PROVIDER_CLIENT_FACTORIES: Record<string, ProviderClientFactory> = {
|
||||
runtimeSettings,
|
||||
}),
|
||||
mock: (logger) => new MockLoadTestAgentClient(logger),
|
||||
"mock-slow": () => new MockSlowProviderClient(),
|
||||
};
|
||||
|
||||
function getCursorACPCommand(
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
import type {
|
||||
AgentCapabilityFlags,
|
||||
AgentClient,
|
||||
AgentLaunchContext,
|
||||
AgentMode,
|
||||
AgentModelDefinition,
|
||||
AgentPersistenceHandle,
|
||||
AgentProvider,
|
||||
AgentSession,
|
||||
AgentSessionConfig,
|
||||
ListModelsOptions,
|
||||
ListModesOptions,
|
||||
ListPersistedAgentsOptions,
|
||||
PersistedAgentDescriptor,
|
||||
} from "../agent-sdk-types.js";
|
||||
|
||||
export const MOCK_SLOW_PROVIDER_ID = "mock-slow";
|
||||
|
||||
const CAPABILITIES: AgentCapabilityFlags = {
|
||||
supportsStreaming: false,
|
||||
supportsSessionPersistence: false,
|
||||
supportsDynamicModes: false,
|
||||
supportsMcpServers: false,
|
||||
supportsReasoningStream: false,
|
||||
supportsToolInvocations: false,
|
||||
supportsRewindConversation: false,
|
||||
supportsRewindFiles: false,
|
||||
supportsRewindBoth: false,
|
||||
};
|
||||
|
||||
function neverResolves<T>(): Promise<T> {
|
||||
return new Promise<T>(() => {});
|
||||
}
|
||||
|
||||
export class MockSlowProviderClient implements AgentClient {
|
||||
readonly provider: AgentProvider = MOCK_SLOW_PROVIDER_ID;
|
||||
readonly capabilities = CAPABILITIES;
|
||||
|
||||
async isAvailable(): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
listModels(_options: ListModelsOptions): Promise<AgentModelDefinition[]> {
|
||||
return neverResolves<AgentModelDefinition[]>();
|
||||
}
|
||||
|
||||
listModes(_options: ListModesOptions): Promise<AgentMode[]> {
|
||||
return neverResolves<AgentMode[]>();
|
||||
}
|
||||
|
||||
async listPersistedAgents(
|
||||
_options?: ListPersistedAgentsOptions,
|
||||
): Promise<PersistedAgentDescriptor[]> {
|
||||
return [];
|
||||
}
|
||||
|
||||
async getDiagnostic(): Promise<{ diagnostic: string }> {
|
||||
return {
|
||||
diagnostic:
|
||||
"Mock slow provider: dev-only. listModels() never resolves so the snapshot manager will time out.",
|
||||
};
|
||||
}
|
||||
|
||||
createSession(
|
||||
_config: AgentSessionConfig,
|
||||
_launchContext?: AgentLaunchContext,
|
||||
): Promise<AgentSession> {
|
||||
throw new Error("Mock slow provider is dev-only; sessions are not supported.");
|
||||
}
|
||||
|
||||
resumeSession(
|
||||
_handle: AgentPersistenceHandle,
|
||||
_overrides?: Partial<AgentSessionConfig>,
|
||||
_launchContext?: AgentLaunchContext,
|
||||
): Promise<AgentSession> {
|
||||
throw new Error("Mock slow provider is dev-only; sessions are not supported.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user