fix: show OpenCode inventory fallback as available

This commit is contained in:
infiniti 2026-05-27 23:00:32 +03:00 committed by GitHub
parent e06c24a041
commit c9e7e49a78
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 67 additions and 29 deletions

View file

@ -884,6 +884,7 @@
},
"status": {
"checking": "Checking...",
"modelsAvailable": "Models available",
"checked": "Checked",
"providerActivity": "Provider Activity",
"notConnected": "Not connected",

View file

@ -884,6 +884,7 @@
},
"status": {
"checking": "Проверка...",
"modelsAvailable": "Модели доступны",
"checked": "Проверено",
"providerActivity": "Активность провайдеров",
"notConnected": "Не подключено",

View file

@ -2759,6 +2759,7 @@ export default interface Resources {
chatGptVerificationDegraded: 'ChatGPT account detected - account verification is currently degraded.';
checked: 'Checked';
checking: 'Checking...';
modelsAvailable: 'Models available';
codexLocalAccountNeedsReconnect: 'Codex has a locally selected ChatGPT account, but the current session needs reconnect.';
codexNativeReady: 'Codex native ready';
codexNativeUnavailable: 'Codex native unavailable';

View file

@ -54,6 +54,7 @@ import {
import {
formatProviderAuthMethodLabelForProvider,
formatProviderAuthModeLabelForProvider,
formatProviderStatusText,
getProviderConnectLabel,
getProviderCurrentRuntimeSummary,
isConnectionManagedRuntimeProvider,
@ -414,7 +415,7 @@ function getProviderUsageLabel(
t
),
})
: provider.statusMessage || t('providerRuntime.usage.notConnected');
: formatProviderStatusText(provider, t);
}
function getCompactOpenCodeProviderDetailMessage(detailMessage?: string | null): string | null {
@ -1150,10 +1151,8 @@ export const ProviderRuntimeSettingsDialog = ({
let connectionStatusLabel: string | null = null;
if (selectedProvider) {
if (!hideConnectionMethodMeta && selectedProvider.authenticated) {
if (!hideConnectionMethodMeta) {
connectionStatusLabel = getProviderUsageLabel(selectedProvider, t);
} else if (!hideConnectionMethodMeta) {
connectionStatusLabel = t('providerRuntime.usage.notConnected');
}
}
const showSelectedProviderSummary = Boolean(selectedProvider) && !connectionManagedRuntime;

View file

@ -425,8 +425,8 @@ export function formatProviderStatusText(
if (isProviderInventoryOnlyFallback(provider)) {
return translateProviderConnection(
t,
'providerRuntime.connectionUi.status.checking',
'Checking...'
'providerRuntime.connectionUi.status.modelsAvailable',
'Models available'
);
}

View file

@ -755,8 +755,9 @@ describe('CLI status visibility during completed install state', () => {
});
expect(host.textContent).toContain('OpenCode');
expect(host.textContent).toContain('Checking...');
expect(host.textContent).toContain('Models available');
expect(host.textContent).toContain('big-pickle');
expect(host.textContent).not.toContain('Checking...');
expect(host.textContent).not.toContain('Provider status unavailable');
expect(host.textContent).not.toContain('Models unavailable for this runtime build');

View file

@ -1972,4 +1972,41 @@ describe('ProviderRuntimeSettingsDialog', () => {
expect(host.textContent).not.toContain('behavior abc123');
expect(host.textContent).not.toContain('Desktop currently exposes status only.');
});
it('shows OpenCode inventory fallback as models available instead of disconnected', async () => {
const host = document.createElement('div');
document.body.appendChild(host);
const root = createRoot(host);
const provider: CliProviderStatus = {
...createOpenCodeProvider(),
supported: false,
authenticated: false,
authMethod: null,
verificationState: 'unknown',
statusMessage: null,
detailMessage: null,
models: ['opencode/big-pickle'],
backend: null,
availableBackends: [],
connection: null,
};
await act(async () => {
root.render(
React.createElement(ProviderRuntimeSettingsDialog, {
open: true,
onOpenChange: vi.fn(),
providers: [provider],
initialProviderId: 'opencode',
projectPath: '/tmp/project-a',
onSelectBackend: vi.fn(),
onRefreshProvider: vi.fn(() => Promise.resolve(undefined)),
})
);
await Promise.resolve();
});
expect(host.textContent).toContain('Models available');
expect(host.textContent).not.toContain('Not connected');
});
});

View file

@ -80,21 +80,19 @@ function createCodexProvider(
},
selectedBackendId: overrides?.selectedBackendId ?? 'codex-native',
resolvedBackendId: overrides?.resolvedBackendId ?? 'codex-native',
availableBackends:
overrides?.availableBackends ??
[
{
id: 'codex-native',
label: 'Codex native',
description: 'Use codex exec JSON mode.',
selectable: true,
recommended: true,
available: true,
state: 'ready',
audience: 'general',
statusMessage: 'Codex native ready',
},
],
availableBackends: overrides?.availableBackends ?? [
{
id: 'codex-native',
label: 'Codex native',
description: 'Use codex exec JSON mode.',
selectable: true,
recommended: true,
available: true,
state: 'ready',
audience: 'general',
statusMessage: 'Codex native ready',
},
],
externalRuntimeDiagnostics: [],
backend:
overrides?.backend ??
@ -123,7 +121,8 @@ function createCodexProvider(
startedAt: null,
},
rateLimits: null,
launchAllowed: Boolean(overrides?.authenticated ?? true) || Boolean(overrides?.apiKeyConfigured),
launchAllowed:
Boolean(overrides?.authenticated ?? true) || Boolean(overrides?.apiKeyConfigured),
launchIssueMessage: null,
launchReadinessState:
Boolean(overrides?.authenticated ?? true) || Boolean(overrides?.apiKeyConfigured)
@ -135,9 +134,7 @@ function createCodexProvider(
};
}
function createOpenCodeProvider(
overrides?: Partial<CliProviderStatus>
): CliProviderStatus {
function createOpenCodeProvider(overrides?: Partial<CliProviderStatus>): CliProviderStatus {
return {
providerId: 'opencode',
displayName: 'OpenCode',
@ -458,7 +455,7 @@ describe('providerConnectionUi', () => {
expect(formatProviderStatusText(provider)).toBe('Codex native ready');
});
it('treats OpenCode inventory-only fallback as still loading', () => {
it('treats OpenCode inventory-only fallback as models available', () => {
const provider = createOpenCodeProvider({
supported: false,
authenticated: false,
@ -483,7 +480,7 @@ describe('providerConnectionUi', () => {
});
expect(isProviderInventoryOnlyFallback(provider)).toBe(true);
expect(formatProviderStatusText(provider)).toBe('Checking...');
expect(formatProviderStatusText(provider)).toBe('Models available');
});
it('surfaces degraded ChatGPT verification warnings instead of flattening them to ready', () => {
@ -508,7 +505,8 @@ describe('providerConnectionUi', () => {
},
rateLimits: null,
launchAllowed: true,
launchIssueMessage: 'ChatGPT account detected, but account verification is currently degraded.',
launchIssueMessage:
'ChatGPT account detected, but account verification is currently degraded.',
launchReadinessState: 'warning_degraded_but_launchable',
},
});