feat(KB-184): add model presets for task creation

- Add model preset types and settings fields with API validation
- Create model preset utility helpers for size-based auto-selection
- Add settings UI for managing model presets (create, edit, delete)
- Integrate preset selection into NewTaskModal with custom override option
- Add inline preset selection to InlineCreateCard component
- Persist modelPresetId in task store and preserve through archive/unarchive
- Add changeset and update AGENTS.md with feature documentation
This commit is contained in:
gsxdsm
2026-03-31 02:04:45 -07:00
parent 501dc588db
commit dfe5601622
17 changed files with 959 additions and 43 deletions

View File

@@ -0,0 +1,47 @@
import type { ModelPreset } from "@kb/core";
export function getPresetByName(presets: ModelPreset[], name: string): ModelPreset | undefined {
const normalizedName = name.trim().toLowerCase();
return presets.find((preset) => preset.name.trim().toLowerCase() === normalizedName);
}
export function applyPresetToSelection(preset: ModelPreset | undefined): {
executorValue: string;
validatorValue: string;
} {
return {
executorValue: preset?.executorProvider && preset?.executorModelId
? `${preset.executorProvider}/${preset.executorModelId}`
: "",
validatorValue: preset?.validatorProvider && preset?.validatorModelId
? `${preset.validatorProvider}/${preset.validatorModelId}`
: "",
};
}
export function getRecommendedPresetForSize(
size: "S" | "M" | "L" | undefined,
defaultPresetBySize: Record<string, string>,
presets: ModelPreset[],
): ModelPreset | undefined {
if (!size) return undefined;
const presetId = defaultPresetBySize[size];
if (!presetId) return undefined;
return presets.find((preset) => preset.id === presetId);
}
export function validatePresetId(id: string): boolean {
return /^[A-Za-z0-9_-]{1,32}$/.test(id);
}
export function generatePresetId(name: string): string {
const slug = name
.trim()
.toLowerCase()
.replace(/[^a-z0-9_-]+/g, "-")
.replace(/-+/g, "-")
.replace(/^[-_]+|[-_]+$/g, "")
.slice(0, 32);
return slug || "preset";
}