fix(cliproxy): fix edit dialog empty model and composite guidance

- P2: Edit dialog no longer seeds empty model string
  Changed `variant.model || ''` to `variant.model ?? undefined`
  Added payload filtering to exclude undefined/empty values before API call
  Prevents unintended model overwrites when user only changes other fields

- P3: Composite --config guidance now uses variant name
  Added profileName to ExecutorConfig interface
  Error message now shows correct variant name instead of default tier provider
  e.g., "ccs cliproxy edit my-mix" instead of "ccs cliproxy edit gemini"
This commit is contained in:
Tam Nhu Tran
2026-02-12 12:56:57 +07:00
parent 399d7e163a
commit 8e6b67bf99
4 changed files with 12 additions and 4 deletions
+1
View File
@@ -611,6 +611,7 @@ async function main(): Promise<void> {
isComposite: profileInfo.isComposite,
compositeTiers: profileInfo.compositeTiers,
compositeDefaultTier: profileInfo.compositeDefaultTier,
profileName: profileInfo.name,
});
} else if (profileInfo.type === 'copilot') {
// COPILOT FLOW: GitHub Copilot subscription via copilot-api proxy
+2 -1
View File
@@ -434,10 +434,11 @@ export async function execClaudeWithCLIProxy(
if (forceConfig && supportsModelConfig(provider)) {
// Block --config for composite variants (per-tier models in config.yaml)
if (cfg.isComposite) {
const variantName = cfg.profileName || provider;
console.log(
warn('Composite variants use per-tier config. Edit config.yaml to change tier models.')
);
console.error(` Use "ccs cliproxy edit ${provider}" to modify composite variants`);
console.error(` Use "ccs cliproxy edit ${variantName}" to modify composite variants`);
process.exit(1);
} else {
await configureProviderModel(provider, true, cfg.customSettingsPath);
+2
View File
@@ -193,6 +193,8 @@ export interface ExecutorConfig {
};
/** Composite variant: which tier is the default */
compositeDefaultTier?: 'opus' | 'sonnet' | 'haiku';
/** Original profile/variant name (e.g., "my-mix" for composite variants) */
profileName?: string;
}
/**
@@ -90,16 +90,20 @@ export function CliproxyEditDialog({ variant, open, onOpenChange }: CliproxyEdit
} else {
singleForm.reset({
provider: variant.provider,
model: variant.model || '',
account: variant.account || '',
model: variant.model ?? undefined,
account: variant.account ?? undefined,
});
}
}, [variant, isComposite, singleForm, compositeForm]);
const onSubmitSingle = async (data: SingleProviderFormData) => {
if (!variant) return;
// Filter out undefined values - backend interprets undefined as "no change"
const payload = Object.fromEntries(
Object.entries(data).filter(([, v]) => v !== undefined && v !== '')
) as SingleProviderFormData;
try {
await updateMutation.mutateAsync({ name: variant.name, data });
await updateMutation.mutateAsync({ name: variant.name, data: payload });
onOpenChange(false);
} catch (error) {
console.error('Failed to update variant:', error);