fix(model-servers): autorise les espaces dans le champ Arguments supplémentaires llama.cpp
Le champ contrôlé de ModelServersPanel/FirstRunWizard perdait les espaces saisis dans les arguments llama.cpp (trim/split prématuré sur chaque frappe au lieu de la seule sérialisation finale) (#113). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -83,6 +83,30 @@ describe("FirstRunWizard (with MockProfileGateway)", () => {
|
||||
expect(cmd.value).toBe("codex-2");
|
||||
});
|
||||
|
||||
it("keeps args spaces while typing and parses them on blur", async () => {
|
||||
const { profile } = renderWizard();
|
||||
await waitForLoaded();
|
||||
await waitFor(() =>
|
||||
expect(
|
||||
(screen.getByLabelText("use Claude Code") as HTMLInputElement).checked,
|
||||
).toBe(true),
|
||||
);
|
||||
|
||||
const args = screen.getByLabelText("Claude Code args") as HTMLInputElement;
|
||||
fireEvent.change(args, {
|
||||
target: { value: "--model claude-sonnet-4-5 --verbose " },
|
||||
});
|
||||
expect(args.value).toBe("--model claude-sonnet-4-5 --verbose ");
|
||||
|
||||
fireEvent.blur(args);
|
||||
fireEvent.click(screen.getByRole("button", { name: "Save and continue" }));
|
||||
|
||||
await waitFor(async () => {
|
||||
const [saved] = await profile.listProfiles();
|
||||
expect(saved.args).toEqual(["--model", "claude-sonnet-4-5", "--verbose"]);
|
||||
});
|
||||
});
|
||||
|
||||
it("detection shows ✓ for claude and ✗ for the rest", async () => {
|
||||
renderWizard();
|
||||
await waitForLoaded();
|
||||
|
||||
@ -20,6 +20,7 @@ import type {
|
||||
HttpChatConfig,
|
||||
LocalModelServerConfig,
|
||||
} from "@/domain";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Button, IconButton, Input, Panel, Toolbar, cn } from "@/shared";
|
||||
import {
|
||||
ModelServersPanel,
|
||||
@ -183,6 +184,16 @@ function ProfileRow({
|
||||
const { profile, selected, available } = entry;
|
||||
const errors = validateProfile(profile);
|
||||
const isOpenCode = profile.structuredAdapter === "openCode";
|
||||
const canonicalArgsText = profile.args.join(" ");
|
||||
const [argsText, setArgsText] = useState(canonicalArgsText);
|
||||
|
||||
useEffect(() => {
|
||||
setArgsText(canonicalArgsText);
|
||||
}, [canonicalArgsText, profile.id]);
|
||||
|
||||
function commitArgs() {
|
||||
onChange({ ...profile, args: parseArgs(argsText) });
|
||||
}
|
||||
|
||||
return (
|
||||
<li className="flex flex-col gap-2 rounded-md border border-border bg-raised p-3">
|
||||
@ -260,8 +271,9 @@ function ProfileRow({
|
||||
<Caption>Arguments</Caption>
|
||||
<Input
|
||||
aria-label={`${profile.name} args`}
|
||||
value={profile.args.join(" ")}
|
||||
onChange={(e) => onChange({ ...profile, args: parseArgs(e.target.value) })}
|
||||
value={argsText}
|
||||
onChange={(e) => setArgsText(e.target.value)}
|
||||
onBlur={commitArgs}
|
||||
/>
|
||||
</label>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user