feat: analysis providers, settings UI, song search, WAV duration fix
- Multi-provider AI analysis (Anthropic, OpenAI, Ollama, Algorithmic) - server-only guards on all provider files; client bundle fix - /settings page with provider status, Ollama model picker, preferences - Song search box on /analyze replacing raw MBID input (debounced, keyboard nav) - Auto-register song via MusicBrainz on POST /api/tracks (no more 404) - Fix WAV duration bug: last section songEnd was double-counting elapsed time - Registry sync comment updated for self-hosted HTTPS git servers Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
63
components/settings/OllamaModelPicker.tsx
Normal file
63
components/settings/OllamaModelPicker.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
"use client";
|
||||
|
||||
import { RECOMMENDED_OLLAMA_MODELS } from "@/lib/analysis/constants";
|
||||
|
||||
interface OllamaModelPickerProps {
|
||||
models: string[];
|
||||
value: string;
|
||||
onChange: (model: string) => void;
|
||||
onRefresh: () => void;
|
||||
refreshing: boolean;
|
||||
}
|
||||
|
||||
export default function OllamaModelPicker({
|
||||
models,
|
||||
value,
|
||||
onChange,
|
||||
onRefresh,
|
||||
refreshing,
|
||||
}: OllamaModelPickerProps) {
|
||||
if (models.length === 0) {
|
||||
return (
|
||||
<p className="text-sm text-zinc-500">
|
||||
No models found. Pull a model with{" "}
|
||||
<code className="text-zinc-400">ollama pull qwen2.5:7b</code> and refresh.
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
<div className="flex flex-col gap-2">
|
||||
{models.map((model) => {
|
||||
const isRecommended = RECOMMENDED_OLLAMA_MODELS.includes(model);
|
||||
return (
|
||||
<label key={model} className="flex items-center gap-3 cursor-pointer group">
|
||||
<input
|
||||
type="radio"
|
||||
name="ollama-model"
|
||||
value={model}
|
||||
checked={value === model}
|
||||
onChange={() => onChange(model)}
|
||||
className="accent-green-500"
|
||||
/>
|
||||
<span className="text-sm text-zinc-300 group-hover:text-zinc-100 transition-colors">
|
||||
{model}
|
||||
</span>
|
||||
{isRecommended && (
|
||||
<span className="text-xs text-amber-400">★ recommended</span>
|
||||
)}
|
||||
</label>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<button
|
||||
onClick={onRefresh}
|
||||
disabled={refreshing}
|
||||
className="text-xs text-zinc-500 hover:text-zinc-300 underline disabled:opacity-50"
|
||||
>
|
||||
{refreshing ? "Refreshing…" : "Refresh model list"}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user