feat(provider): align provider and model workflows (#324)
* feat(provider): align provider and model workflows * fix(provider): clear gemini/github flags and use local ollama default * fix(provider): preserve explicit startup provider selection * fix(provider): clear env when deleting last profile * chore(provider): apply review nits in ProviderManager * fix(provider): preserve explicit env on last-profile delete * fix(provider): preserve explicit env when profile marker is stale --------- Co-authored-by: Gitlawb <gitlawb@users.noreply.github.com>
This commit is contained in:
@@ -12,6 +12,10 @@ import { isBilledAsExtraUsage } from '../../utils/extraUsage.js';
|
||||
import { clearFastModeCooldown, isFastModeAvailable, isFastModeEnabled, isFastModeSupportedByModel } from '../../utils/fastMode.js';
|
||||
import { MODEL_ALIASES } from '../../utils/model/aliases.js';
|
||||
import { checkOpus1mAccess, checkSonnet1mAccess } from '../../utils/model/check1mAccess.js';
|
||||
import type { ModelOption } from '../../utils/model/modelOptions.js';
|
||||
import { discoverOpenAICompatibleModelOptions } from '../../utils/model/openaiModelDiscovery.js';
|
||||
import { getAPIProvider } from '../../utils/model/providers.js';
|
||||
import { getActiveOpenAIModelOptionsCache, setActiveOpenAIModelOptionsCache } from '../../utils/providerProfiles.js';
|
||||
import { getDefaultMainLoopModelSetting, isOpus1mMergeEnabled, renderDefaultModelSetting } from '../../utils/model/model.js';
|
||||
import { isModelAllowed } from '../../utils/model/modelAllowlist.js';
|
||||
import { validateModel } from '../../utils/model/validateModel.js';
|
||||
@@ -268,6 +272,33 @@ function _temp8(s_0) {
|
||||
function _temp7(s) {
|
||||
return s.mainLoopModel;
|
||||
}
|
||||
function haveSameModelOptions(left: ModelOption[], right: ModelOption[]): boolean {
|
||||
if (left.length !== right.length) {
|
||||
return false;
|
||||
}
|
||||
return left.every((option, index) => {
|
||||
const other = right[index];
|
||||
return other !== undefined && option.value === other.value && option.label === other.label && option.description === other.description && option.descriptionForModel === other.descriptionForModel;
|
||||
});
|
||||
}
|
||||
async function refreshOpenAIModelOptionsCache(): Promise<void> {
|
||||
if (getAPIProvider() !== 'openai') {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const discoveredOptions = await discoverOpenAICompatibleModelOptions();
|
||||
if (discoveredOptions.length === 0) {
|
||||
return;
|
||||
}
|
||||
const currentOptions = getActiveOpenAIModelOptionsCache();
|
||||
if (haveSameModelOptions(currentOptions, discoveredOptions)) {
|
||||
return;
|
||||
}
|
||||
setActiveOpenAIModelOptionsCache(discoveredOptions);
|
||||
} catch {
|
||||
// Keep /model usable even if endpoint discovery fails.
|
||||
}
|
||||
}
|
||||
export const call: LocalJSXCommandCall = async (onDone, _context, args) => {
|
||||
args = args?.trim() || '';
|
||||
if (COMMON_INFO_ARGS.includes(args)) {
|
||||
@@ -288,6 +319,7 @@ export const call: LocalJSXCommandCall = async (onDone, _context, args) => {
|
||||
});
|
||||
return <SetModelAndClose args={args} onDone={onDone} />;
|
||||
}
|
||||
await refreshOpenAIModelOptionsCache();
|
||||
return <ModelPickerWrapper onDone={onDone} />;
|
||||
};
|
||||
function renderModelLabel(model: string | null): string {
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import type { Command } from '../../commands.js'
|
||||
import { shouldInferenceConfigCommandBeImmediate } from '../../utils/immediateCommand.js'
|
||||
|
||||
export default {
|
||||
const provider = {
|
||||
type: 'local-jsx',
|
||||
name: 'provider',
|
||||
description: 'Set up and save a third-party provider profile for OpenClaude',
|
||||
get immediate() {
|
||||
return shouldInferenceConfigCommandBeImmediate()
|
||||
},
|
||||
description: 'Manage API provider profiles',
|
||||
load: () => import('./provider.js'),
|
||||
} satisfies Command
|
||||
|
||||
export default provider
|
||||
|
||||
@@ -2,6 +2,7 @@ import * as React from 'react'
|
||||
|
||||
import type { LocalJSXCommandCall, LocalJSXCommandOnDone } from '../../types/command.js'
|
||||
import { COMMON_HELP_ARGS, COMMON_INFO_ARGS } from '../../constants/xml.js'
|
||||
import { ProviderManager } from '../../components/ProviderManager.js'
|
||||
import TextInput from '../../components/TextInput.js'
|
||||
import {
|
||||
Select,
|
||||
@@ -1289,22 +1290,34 @@ export function ProviderWizard({
|
||||
}
|
||||
|
||||
export const call: LocalJSXCommandCall = async (onDone, _context, args) => {
|
||||
const normalizedArgs = args?.trim().toLowerCase() || ''
|
||||
const trimmedArgs = args?.trim().toLowerCase() ?? ''
|
||||
|
||||
if (COMMON_INFO_ARGS.includes(normalizedArgs)) {
|
||||
onDone(buildUsageText(), { display: 'system' })
|
||||
return null
|
||||
if (
|
||||
COMMON_HELP_ARGS.includes(trimmedArgs) ||
|
||||
COMMON_INFO_ARGS.includes(trimmedArgs) ||
|
||||
trimmedArgs === 'help' ||
|
||||
trimmedArgs === '--help' ||
|
||||
trimmedArgs === '-h'
|
||||
) {
|
||||
onDone(
|
||||
'Run /provider to add, edit, delete, or activate provider profiles. The active provider controls base URL, model, and API key.',
|
||||
{ display: 'system' },
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if (COMMON_HELP_ARGS.includes(normalizedArgs)) {
|
||||
onDone(buildUsageText(), { display: 'system' })
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<ProviderManager
|
||||
mode="manage"
|
||||
onDone={result => {
|
||||
const message =
|
||||
result?.message ??
|
||||
(result?.action === 'saved'
|
||||
? 'Provider profile updated'
|
||||
: 'Provider manager closed')
|
||||
|
||||
if (normalizedArgs) {
|
||||
onDone('Usage: /provider', { display: 'system' })
|
||||
return null
|
||||
}
|
||||
|
||||
return <ProviderWizard onDone={onDone} />
|
||||
onDone(message, { display: 'system' })
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user