techfreakworm commited on
Commit
97db435
·
unverified ·
1 Parent(s): 19d6f18

feat(web): seed control with -1=random + randomize button

Browse files
web/src/components/ParamsPanel.tsx CHANGED
@@ -13,6 +13,39 @@ function renderControl(
13
  ) {
14
  const id = `param-${s.name}`;
15
  const current: unknown = values[s.name] ?? s.default;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  if (s.type === "float" || s.type === "int") {
17
  const n = typeof current === "number" ? current : Number(current);
18
  return (
 
13
  ) {
14
  const id = `param-${s.name}`;
15
  const current: unknown = values[s.name] ?? s.default;
16
+ if (s.name === "seed") {
17
+ const v = (values[s.name] ?? s.default) as number;
18
+ return (
19
+ <div key={s.name} className="space-y-1.5">
20
+ <label htmlFor={id} className="label-mono">{s.label}</label>
21
+ <div className="flex items-center gap-3">
22
+ <input
23
+ id={id}
24
+ aria-label={s.label}
25
+ type="number"
26
+ min={s.min}
27
+ step={s.step ?? 1}
28
+ value={v}
29
+ onChange={(e) => set(s.name, Number(e.target.value))}
30
+ className="field-input !w-44 font-mono text-[12px] py-1"
31
+ />
32
+ <button
33
+ type="button"
34
+ onClick={() => set(s.name, -1)}
35
+ className="label-mono hover:text-foreground transition-colors"
36
+ >
37
+ ↻ random
38
+ </button>
39
+ {v === -1 && (
40
+ <span className="label-mono text-muted-foreground">(random per generate)</span>
41
+ )}
42
+ </div>
43
+ {s.help && (
44
+ <p className="text-[11px] text-muted-foreground/80 italic">{s.help}</p>
45
+ )}
46
+ </div>
47
+ );
48
+ }
49
  if (s.type === "float" || s.type === "int") {
50
  const n = typeof current === "number" ? current : Number(current);
51
  return (
web/src/test/ParamsPanel.test.tsx CHANGED
@@ -58,3 +58,26 @@ describe("ParamsPanel groups", () => {
58
  expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ top_p: 0.6 }));
59
  });
60
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ top_p: 0.6 }));
59
  });
60
  });
61
+
62
+ describe("ParamsPanel seed control", () => {
63
+ it("renders an int input plus a randomize button for seed", () => {
64
+ const specs: ParamSpec[] = [
65
+ { name: "seed", label: "Seed", type: "int", default: -1, min: -1, step: 1, group: "advanced" },
66
+ ];
67
+ render(<ParamsPanel specs={specs} values={{}} onChange={() => {}} />);
68
+ fireEvent.click(screen.getByText(/advanced/i));
69
+ expect(screen.getByLabelText(/^seed$/i)).toHaveAttribute("type", "number");
70
+ expect(screen.getByRole("button", { name: /random/i })).toBeInTheDocument();
71
+ });
72
+
73
+ it("clicking randomize sets seed to -1 via onChange", () => {
74
+ const specs: ParamSpec[] = [
75
+ { name: "seed", label: "Seed", type: "int", default: -1, min: -1, step: 1, group: "advanced" },
76
+ ];
77
+ const onChange = vi.fn();
78
+ render(<ParamsPanel specs={specs} values={{ seed: 42 }} onChange={onChange} />);
79
+ fireEvent.click(screen.getByText(/advanced/i));
80
+ fireEvent.click(screen.getByRole("button", { name: /random/i }));
81
+ expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ seed: -1 }));
82
+ });
83
+ });