refactoring: switched to gpt-5-nano for commit message generation

Remove commitMessageModel from persisted settings and defaults
Eliminate UI controls and state for commitMessageModel in GitSettings and config store
Update backend and persistence layers to stop reading or writing commitMessageModel
This commit is contained in:
Bohdan Triapitsyn
2026-01-19 03:42:34 +02:00
parent ce1622b1e2
commit 494da1315c
8 changed files with 129 additions and 173 deletions
@@ -1,64 +1,23 @@
import React from 'react';
import { RiInformationLine } from '@remixicon/react';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { ModelSelector } from '@/components/sections/agents/ModelSelector';
import { updateDesktopSettings } from '@/lib/persistence';
import { isDesktopRuntime, getDesktopSettings } from '@/lib/desktop';
import { useConfigStore } from '@/stores/useConfigStore';
import { getRegisteredRuntimeAPIs } from '@/contexts/runtimeAPIRegistry';
const FALLBACK_PROVIDER_ID = 'opencode';
const FALLBACK_MODEL_ID = 'big-pickle';
const getDisplayModel = (
storedModel: string | undefined,
providers: Array<{ id: string; models: Array<{ id: string }> }>
): { providerId: string; modelId: string } => {
if (storedModel) {
const parts = storedModel.split('/');
if (parts.length === 2 && parts[0] && parts[1]) {
return { providerId: parts[0], modelId: parts[1] };
}
}
const fallbackProvider = providers.find(p => p.id === FALLBACK_PROVIDER_ID);
if (fallbackProvider?.models.some(m => m.id === FALLBACK_MODEL_ID)) {
return { providerId: FALLBACK_PROVIDER_ID, modelId: FALLBACK_MODEL_ID };
}
const firstProvider = providers[0];
if (firstProvider?.models[0]) {
return { providerId: firstProvider.id, modelId: firstProvider.models[0].id };
}
return { providerId: '', modelId: '' };
};
export const GitSettings: React.FC = () => {
const settingsCommitMessageModel = useConfigStore((state) => state.settingsCommitMessageModel);
const setSettingsCommitMessageModel = useConfigStore((state) => state.setSettingsCommitMessageModel);
const settingsGitmojiEnabled = useConfigStore((state) => state.settingsGitmojiEnabled);
const setSettingsGitmojiEnabled = useConfigStore((state) => state.setSettingsGitmojiEnabled);
const providers = useConfigStore((state) => state.providers);
const [isLoading, setIsLoading] = React.useState(true);
const opencodeProviders = React.useMemo(() => {
return providers.filter((provider) => provider.id === FALLBACK_PROVIDER_ID);
}, [providers]);
const parsedModel = React.useMemo(() => {
const effectiveStoredModel = settingsCommitMessageModel?.startsWith(`${FALLBACK_PROVIDER_ID}/`)
? settingsCommitMessageModel
: undefined;
return getDisplayModel(effectiveStoredModel, opencodeProviders);
}, [settingsCommitMessageModel, opencodeProviders]);
// Load current settings
React.useEffect(() => {
const loadSettings = async () => {
try {
let data: { commitMessageModel?: string; gitmojiEnabled?: boolean } | null = null;
let data: { gitmojiEnabled?: boolean } | null = null;
// 1. Desktop runtime (Tauri)
if (isDesktopRuntime()) {
@@ -72,7 +31,6 @@ export const GitSettings: React.FC = () => {
const settings = result?.settings;
if (settings) {
data = {
commitMessageModel: typeof settings.commitMessageModel === 'string' ? settings.commitMessageModel : undefined,
gitmojiEnabled: typeof (settings as Record<string, unknown>).gitmojiEnabled === 'boolean'
? ((settings as Record<string, unknown>).gitmojiEnabled as boolean)
: undefined,
@@ -96,10 +54,6 @@ export const GitSettings: React.FC = () => {
}
if (data) {
const model = typeof data.commitMessageModel === 'string' && data.commitMessageModel.trim().length > 0
? data.commitMessageModel.trim()
: undefined;
setSettingsCommitMessageModel(model);
if (typeof data.gitmojiEnabled === 'boolean') {
setSettingsGitmojiEnabled(data.gitmojiEnabled);
}
@@ -112,20 +66,7 @@ export const GitSettings: React.FC = () => {
}
};
loadSettings();
}, [setSettingsCommitMessageModel, setSettingsGitmojiEnabled]);
const handleModelChange = React.useCallback(async (providerId: string, modelId: string) => {
const newValue = providerId && modelId ? `${providerId}/${modelId}` : undefined;
setSettingsCommitMessageModel(newValue);
try {
await updateDesktopSettings({
commitMessageModel: newValue ?? '',
});
} catch (error) {
console.warn('Failed to save commit message model:', error);
}
}, [setSettingsCommitMessageModel]);
}, [setSettingsGitmojiEnabled]);
const handleGitmojiChange = React.useCallback(async (event: React.ChangeEvent<HTMLInputElement>) => {
const enabled = event.target.checked;
@@ -160,20 +101,6 @@ export const GitSettings: React.FC = () => {
</div>
<div className="space-y-3">
<fieldset className="flex flex-col gap-1.5">
<legend className="typography-ui-label text-muted-foreground">Model for generation</legend>
<ModelSelector
providerId={parsedModel.providerId}
modelId={parsedModel.modelId}
onChange={handleModelChange}
allowedProviderIds={[FALLBACK_PROVIDER_ID]}
/>
<p className="typography-meta text-muted-foreground mt-1">
This model will be used to analyze diffs and suggest commit messages.
{!settingsCommitMessageModel && <> Default: <span className="text-foreground">opencode/big-pickle</span></>}
</p>
</fieldset>
<div className="flex flex-col gap-2">
<label className="flex items-center gap-2 cursor-pointer">
<input
@@ -374,7 +374,7 @@ export const useChatScrollManager = ({
? (container.querySelector(`[data-message-id="${persistedAnchor.anchorId}"]`) as HTMLElement | null)
: null;
const messageHeight = anchorElement?.offsetHeight ?? 0;
const restoredSpacerHeight = Math.max(0, persistedAnchor.spacerHeight - messageHeight);
const restoredSpacerHeight = Math.max(0, persistedAnchor.spacerHeight - (messageHeight - 50));
flushSync(() => {
setAnchorId(persistedAnchor.anchorId);
-1
View File
@@ -59,7 +59,6 @@ export type DesktopSettings = {
defaultGitIdentityId?: string; // ''/undefined = unset, 'global' or profile id
autoCreateWorktree?: boolean;
queueModeEnabled?: boolean;
commitMessageModel?: string; // format: "provider/model"
gitmojiEnabled?: boolean;
// User-added skills catalogs (persisted to ~/.config/openchamber/settings.json)
-8
View File
@@ -47,11 +47,6 @@ const persistToLocalStorage = (settings: DesktopSettings) => {
} else {
localStorage.removeItem('pinnedDirectories');
}
if (settings.commitMessageModel) {
localStorage.setItem('commitMessageModel', settings.commitMessageModel);
} else {
localStorage.removeItem('commitMessageModel');
}
if (typeof settings.gitmojiEnabled === 'boolean') {
localStorage.setItem('gitmojiEnabled', String(settings.gitmojiEnabled));
} else {
@@ -271,9 +266,6 @@ const sanitizeWebSettings = (payload: unknown): DesktopSettings | null => {
if (typeof candidate.autoCreateWorktree === 'boolean') {
result.autoCreateWorktree = candidate.autoCreateWorktree;
}
if (typeof candidate.commitMessageModel === 'string' && candidate.commitMessageModel.length > 0) {
result.commitMessageModel = candidate.commitMessageModel;
}
if (typeof candidate.gitmojiEnabled === 'boolean') {
result.gitmojiEnabled = candidate.gitmojiEnabled;
}
-15
View File
@@ -25,7 +25,6 @@ interface OpenChamberDefaults {
defaultVariant?: string;
defaultAgent?: string;
autoCreateWorktree?: boolean;
commitMessageModel?: string;
gitmojiEnabled?: boolean;
}
@@ -39,7 +38,6 @@ const fetchOpenChamberDefaults = async (): Promise<OpenChamberDefaults> => {
defaultVariant: settings?.defaultVariant,
defaultAgent: settings?.defaultAgent,
autoCreateWorktree: settings?.autoCreateWorktree,
commitMessageModel: settings?.commitMessageModel,
gitmojiEnabled: settings?.gitmojiEnabled,
};
}
@@ -54,7 +52,6 @@ const fetchOpenChamberDefaults = async (): Promise<OpenChamberDefaults> => {
const defaultModel = typeof data?.defaultModel === 'string' ? data.defaultModel.trim() : '';
const defaultVariant = typeof data?.defaultVariant === 'string' ? data.defaultVariant.trim() : '';
const defaultAgent = typeof data?.defaultAgent === 'string' ? data.defaultAgent.trim() : '';
const commitMessageModel = typeof data?.commitMessageModel === 'string' ? data.commitMessageModel.trim() : '';
const gitmojiEnabled = typeof data?.gitmojiEnabled === 'boolean' ? data.gitmojiEnabled : undefined;
return {
@@ -62,7 +59,6 @@ const fetchOpenChamberDefaults = async (): Promise<OpenChamberDefaults> => {
defaultVariant: defaultVariant.length > 0 ? defaultVariant : undefined,
defaultAgent: defaultAgent.length > 0 ? defaultAgent : undefined,
autoCreateWorktree: typeof data?.autoCreateWorktree === 'boolean' ? data.autoCreateWorktree : undefined,
commitMessageModel: commitMessageModel.length > 0 ? commitMessageModel : undefined,
gitmojiEnabled,
};
}
@@ -83,7 +79,6 @@ const fetchOpenChamberDefaults = async (): Promise<OpenChamberDefaults> => {
const defaultModel = typeof data?.defaultModel === 'string' ? data.defaultModel.trim() : '';
const defaultVariant = typeof data?.defaultVariant === 'string' ? data.defaultVariant.trim() : '';
const defaultAgent = typeof data?.defaultAgent === 'string' ? data.defaultAgent.trim() : '';
const commitMessageModel = typeof data?.commitMessageModel === 'string' ? data.commitMessageModel.trim() : '';
const gitmojiEnabled = typeof data?.gitmojiEnabled === 'boolean' ? data.gitmojiEnabled : undefined;
return {
@@ -91,7 +86,6 @@ const fetchOpenChamberDefaults = async (): Promise<OpenChamberDefaults> => {
defaultVariant: defaultVariant.length > 0 ? defaultVariant : undefined,
defaultAgent: defaultAgent.length > 0 ? defaultAgent : undefined,
autoCreateWorktree: typeof data?.autoCreateWorktree === 'boolean' ? data.autoCreateWorktree : undefined,
commitMessageModel: commitMessageModel.length > 0 ? commitMessageModel : undefined,
gitmojiEnabled,
};
} catch {
@@ -384,7 +378,6 @@ interface ConfigStore {
settingsDefaultVariant: string | undefined;
settingsDefaultAgent: string | undefined;
settingsAutoCreateWorktree: boolean;
settingsCommitMessageModel: string | undefined; // format: "provider/model"
settingsGitmojiEnabled: boolean;
activateDirectory: (directory: string | null | undefined) => Promise<void>;
@@ -402,7 +395,6 @@ interface ConfigStore {
setSettingsDefaultVariant: (variant: string | undefined) => void;
setSettingsDefaultAgent: (agent: string | undefined) => void;
setSettingsAutoCreateWorktree: (enabled: boolean) => void;
setSettingsCommitMessageModel: (model: string | undefined) => void;
setSettingsGitmojiEnabled: (enabled: boolean) => void;
saveAgentModelSelection: (agentName: string, providerId: string, modelId: string) => void;
getAgentModelSelection: (agentName: string) => { providerId: string; modelId: string } | null;
@@ -447,7 +439,6 @@ export const useConfigStore = create<ConfigStore>()(
settingsDefaultVariant: undefined,
settingsDefaultAgent: undefined,
settingsAutoCreateWorktree: false,
settingsCommitMessageModel: undefined,
settingsGitmojiEnabled: false,
activateDirectory: async (directory) => {
@@ -892,7 +883,6 @@ export const useConfigStore = create<ConfigStore>()(
settingsDefaultVariant: openChamberDefaults.defaultVariant,
settingsDefaultAgent: openChamberDefaults.defaultAgent,
settingsAutoCreateWorktree: openChamberDefaults.autoCreateWorktree ?? false,
settingsCommitMessageModel: openChamberDefaults.commitMessageModel,
settingsGitmojiEnabled: openChamberDefaults.gitmojiEnabled ?? false,
directoryScoped: {
...state.directoryScoped,
@@ -1314,10 +1304,6 @@ export const useConfigStore = create<ConfigStore>()(
set({ settingsAutoCreateWorktree: enabled });
},
setSettingsCommitMessageModel: (model) => {
set({ settingsCommitMessageModel: model });
},
setSettingsGitmojiEnabled: (enabled: boolean) => {
set({ settingsGitmojiEnabled: enabled });
},
@@ -1427,7 +1413,6 @@ export const useConfigStore = create<ConfigStore>()(
settingsDefaultVariant: state.settingsDefaultVariant,
settingsDefaultAgent: state.settingsDefaultAgent,
settingsAutoCreateWorktree: state.settingsAutoCreateWorktree,
settingsCommitMessageModel: state.settingsCommitMessageModel,
settingsGitmojiEnabled: state.settingsGitmojiEnabled,
}),
},