feat(model-server): wizard V2 config modèles locaux — source, options structurées & preview

Refonte UX du wizard de configuration des modèles locaux du serveur
llama.cpp intégré, alignée sur la source Hugging Face et les options backend.

- choix de source sans jargon (chemin local .gguf vs dépôt Hugging Face) ;
- champs structurés -ngl (gpu_layers), -c (context_size), --jinja, --host ;
- zone d'arguments libres avec alerte sur les flags réservés ;
- preview de la commande via le backend (previewModelServerCommand, debounced) ;
- gateway/ports et mock adaptés au contrat V2.

QA : Vitest 22 verts, tsc/build OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-12 14:32:04 +02:00
parent 38aecf2cac
commit efa081b074
10 changed files with 794 additions and 143 deletions

View File

@ -11,7 +11,11 @@
import { useCallback, useEffect, useState } from "react";
import type { GatewayError, LocalModelServerConfig } from "@/domain";
import type {
GatewayError,
LocalModelServerConfig,
ModelServerCommandPreview,
} from "@/domain";
import { useGateways } from "@/app/di";
/** What the model-server UI needs from this hook. */
@ -28,6 +32,14 @@ export interface ModelServersViewModel {
save: (config: LocalModelServerConfig) => Promise<LocalModelServerConfig | null>;
/** Deletes a server by id; returns `true` on success. */
remove: (serverId: string) => Promise<boolean>;
/**
* Asks the backend to build the `llama-server` command line for a draft
* (never reconstructed client-side). Returns `null` when the draft is
* invalid — the editor shows a placeholder instead of a stale command.
*/
preview: (
config: LocalModelServerConfig,
) => Promise<ModelServerCommandPreview | null>;
/** Clears the current error banner. */
clearError: () => void;
}
@ -120,7 +132,20 @@ export function useModelServers(): ModelServersViewModel {
[modelServer],
);
const preview = useCallback(
async (config: LocalModelServerConfig) => {
try {
return await modelServer.previewModelServerCommand(config);
} catch {
// A preview is best-effort UI sugar: an invalid draft (e.g. no source)
// simply yields no command, without touching the CRUD error banner.
return null;
}
},
[modelServer],
);
const clearError = useCallback(() => setError(null), []);
return { servers, error, busy, reload, save, remove, clearError };
return { servers, error, busy, reload, save, remove, preview, clearError };
}