mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-30 06:12:03 +00:00
feat: add default AI profile selection to settings view
- Introduced default AI profile management in the settings view, allowing users to select a default profile for new features. - Updated the Add Feature dialog to utilize the selected AI profile, setting default model and thinking level based on the chosen profile. - Enhanced the Feature Defaults section to display and manage the default AI profile, including a dropdown for selection and relevant information display.
This commit is contained in:
@@ -126,16 +126,25 @@ export function AddFeatureDialog({
|
||||
enhancementModel,
|
||||
defaultPlanningMode,
|
||||
defaultRequirePlanApproval,
|
||||
defaultAIProfileId,
|
||||
useWorktrees,
|
||||
} = useAppStore();
|
||||
|
||||
// Sync defaults when dialog opens
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
// Find the default profile if one is set
|
||||
const defaultProfile = defaultAIProfileId
|
||||
? aiProfiles.find((p) => p.id === defaultAIProfileId)
|
||||
: null;
|
||||
|
||||
setNewFeature((prev) => ({
|
||||
...prev,
|
||||
skipTests: defaultSkipTests,
|
||||
branchName: defaultBranch || "",
|
||||
// Use default profile's model/thinkingLevel if set, else fallback to defaults
|
||||
model: defaultProfile?.model ?? "opus",
|
||||
thinkingLevel: defaultProfile?.thinkingLevel ?? "none",
|
||||
}));
|
||||
setUseCurrentBranch(true);
|
||||
setPlanningMode(defaultPlanningMode);
|
||||
@@ -147,6 +156,8 @@ export function AddFeatureDialog({
|
||||
defaultBranch,
|
||||
defaultPlanningMode,
|
||||
defaultRequirePlanApproval,
|
||||
defaultAIProfileId,
|
||||
aiProfiles,
|
||||
]);
|
||||
|
||||
const handleAdd = () => {
|
||||
|
||||
@@ -43,6 +43,9 @@ export function SettingsView() {
|
||||
setDefaultPlanningMode,
|
||||
defaultRequirePlanApproval,
|
||||
setDefaultRequirePlanApproval,
|
||||
defaultAIProfileId,
|
||||
setDefaultAIProfileId,
|
||||
aiProfiles,
|
||||
} = useAppStore();
|
||||
|
||||
// Convert electron Project to settings-view Project type
|
||||
@@ -127,12 +130,15 @@ export function SettingsView() {
|
||||
useWorktrees={useWorktrees}
|
||||
defaultPlanningMode={defaultPlanningMode}
|
||||
defaultRequirePlanApproval={defaultRequirePlanApproval}
|
||||
defaultAIProfileId={defaultAIProfileId}
|
||||
aiProfiles={aiProfiles}
|
||||
onShowProfilesOnlyChange={setShowProfilesOnly}
|
||||
onDefaultSkipTestsChange={setDefaultSkipTests}
|
||||
onEnableDependencyBlockingChange={setEnableDependencyBlocking}
|
||||
onUseWorktreesChange={setUseWorktrees}
|
||||
onDefaultPlanningModeChange={setDefaultPlanningMode}
|
||||
onDefaultRequirePlanApprovalChange={setDefaultRequirePlanApproval}
|
||||
onDefaultAIProfileIdChange={setDefaultAIProfileId}
|
||||
/>
|
||||
);
|
||||
case "danger":
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Label } from "@/components/ui/label";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import {
|
||||
FlaskConical, Settings2, TestTube, GitBranch, AlertCircle,
|
||||
Zap, ClipboardList, FileText, ScrollText, ShieldCheck
|
||||
Zap, ClipboardList, FileText, ScrollText, ShieldCheck, User
|
||||
} from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import type { AIProfile } from "@/store/app-store";
|
||||
|
||||
type PlanningMode = 'skip' | 'lite' | 'spec' | 'full';
|
||||
|
||||
@@ -22,12 +23,15 @@ interface FeatureDefaultsSectionProps {
|
||||
useWorktrees: boolean;
|
||||
defaultPlanningMode: PlanningMode;
|
||||
defaultRequirePlanApproval: boolean;
|
||||
defaultAIProfileId: string | null;
|
||||
aiProfiles: AIProfile[];
|
||||
onShowProfilesOnlyChange: (value: boolean) => void;
|
||||
onDefaultSkipTestsChange: (value: boolean) => void;
|
||||
onEnableDependencyBlockingChange: (value: boolean) => void;
|
||||
onUseWorktreesChange: (value: boolean) => void;
|
||||
onDefaultPlanningModeChange: (value: PlanningMode) => void;
|
||||
onDefaultRequirePlanApprovalChange: (value: boolean) => void;
|
||||
onDefaultAIProfileIdChange: (value: string | null) => void;
|
||||
}
|
||||
|
||||
export function FeatureDefaultsSection({
|
||||
@@ -37,13 +41,20 @@ export function FeatureDefaultsSection({
|
||||
useWorktrees,
|
||||
defaultPlanningMode,
|
||||
defaultRequirePlanApproval,
|
||||
defaultAIProfileId,
|
||||
aiProfiles,
|
||||
onShowProfilesOnlyChange,
|
||||
onDefaultSkipTestsChange,
|
||||
onEnableDependencyBlockingChange,
|
||||
onUseWorktreesChange,
|
||||
onDefaultPlanningModeChange,
|
||||
onDefaultRequirePlanApprovalChange,
|
||||
onDefaultAIProfileIdChange,
|
||||
}: FeatureDefaultsSectionProps) {
|
||||
// Find the selected profile name for display
|
||||
const selectedProfile = defaultAIProfileId
|
||||
? aiProfiles.find((p) => p.id === defaultAIProfileId)
|
||||
: null;
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
@@ -169,6 +180,49 @@ export function FeatureDefaultsSection({
|
||||
{/* Separator */}
|
||||
{defaultPlanningMode === 'skip' && <div className="border-t border-border/30" />}
|
||||
|
||||
{/* Default AI Profile */}
|
||||
<div className="group flex items-start space-x-3 p-3 rounded-xl hover:bg-accent/30 transition-colors duration-200 -mx-3">
|
||||
<div className="w-10 h-10 mt-0.5 rounded-xl flex items-center justify-center shrink-0 bg-brand-500/10">
|
||||
<User className="w-5 h-5 text-brand-500" />
|
||||
</div>
|
||||
<div className="flex-1 space-y-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label className="text-foreground font-medium">
|
||||
Default AI Profile
|
||||
</Label>
|
||||
<Select
|
||||
value={defaultAIProfileId ?? "none"}
|
||||
onValueChange={(v: string) => onDefaultAIProfileIdChange(v === "none" ? null : v)}
|
||||
>
|
||||
<SelectTrigger
|
||||
className="w-[180px] h-8"
|
||||
data-testid="default-ai-profile-select"
|
||||
>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="none">
|
||||
<span className="text-muted-foreground">None (pick manually)</span>
|
||||
</SelectItem>
|
||||
{aiProfiles.map((profile) => (
|
||||
<SelectItem key={profile.id} value={profile.id}>
|
||||
<span>{profile.name}</span>
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground/80 leading-relaxed">
|
||||
{selectedProfile
|
||||
? `New features will use the "${selectedProfile.name}" profile (${selectedProfile.model}, ${selectedProfile.thinkingLevel} thinking).`
|
||||
: "Pre-select an AI profile when creating new features. Choose \"None\" to pick manually each time."}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Separator */}
|
||||
<div className="border-t border-border/30" />
|
||||
|
||||
{/* Profiles Only Setting */}
|
||||
<div className="group flex items-start space-x-3 p-3 rounded-xl hover:bg-accent/30 transition-colors duration-200 -mx-3">
|
||||
<Checkbox
|
||||
|
||||
@@ -494,6 +494,7 @@ export interface AppState {
|
||||
|
||||
defaultPlanningMode: PlanningMode;
|
||||
defaultRequirePlanApproval: boolean;
|
||||
defaultAIProfileId: string | null;
|
||||
|
||||
// Plan Approval State
|
||||
// When a plan requires user approval, this holds the pending approval details
|
||||
@@ -742,6 +743,7 @@ export interface AppActions {
|
||||
|
||||
setDefaultPlanningMode: (mode: PlanningMode) => void;
|
||||
setDefaultRequirePlanApproval: (require: boolean) => void;
|
||||
setDefaultAIProfileId: (profileId: string | null) => void;
|
||||
|
||||
// Plan Approval actions
|
||||
setPendingPlanApproval: (approval: {
|
||||
@@ -841,6 +843,7 @@ const initialState: AppState = {
|
||||
specCreatingForProject: null,
|
||||
defaultPlanningMode: 'skip' as PlanningMode,
|
||||
defaultRequirePlanApproval: false,
|
||||
defaultAIProfileId: null,
|
||||
pendingPlanApproval: null,
|
||||
};
|
||||
|
||||
@@ -2265,6 +2268,7 @@ export const useAppStore = create<AppState & AppActions>()(
|
||||
|
||||
setDefaultPlanningMode: (mode) => set({ defaultPlanningMode: mode }),
|
||||
setDefaultRequirePlanApproval: (require) => set({ defaultRequirePlanApproval: require }),
|
||||
setDefaultAIProfileId: (profileId) => set({ defaultAIProfileId: profileId }),
|
||||
|
||||
// Plan Approval actions
|
||||
setPendingPlanApproval: (approval) => set({ pendingPlanApproval: approval }),
|
||||
@@ -2340,6 +2344,7 @@ export const useAppStore = create<AppState & AppActions>()(
|
||||
boardBackgroundByProject: state.boardBackgroundByProject,
|
||||
defaultPlanningMode: state.defaultPlanningMode,
|
||||
defaultRequirePlanApproval: state.defaultRequirePlanApproval,
|
||||
defaultAIProfileId: state.defaultAIProfileId,
|
||||
}),
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user