fix(lens): list recorded agents in the run now dialog

The run now agent field used a native datalist, whose suggestions do not show inside the modal dialog, so the agent list looked empty even though /lens/agents returned names. Use the same Combobox as investigation setup.
This commit is contained in:
Ishaan Jaff 2026-10-03 17:24:04 -07:00
parent 7de044b71e
commit 2cffbdbc95
No known key found for this signature in database
2 changed files with 66 additions and 12 deletions

View file

@ -280,6 +280,45 @@ it("runs with saved settings from Run now without opening setup, then accepts an
});
});
it("lists recorded agents in Run now and runs the one picked from the list", async () => {
testQueryClient.clear();
vi.mocked(apiClient.get).mockImplementation(async (path) => {
if (path === "/lens")
return {
lenses: [lens],
tracing_enabled: true,
workers: [
{
id: "worker",
name: "Worker",
revoked: false,
analysis_key_id: "a".repeat(64),
scope: lens.scope,
last_seen: new Date().toISOString(),
},
],
};
if (path === "/lens/lens/runs") return lens.jobs;
if (path === "/lens/agents") return ["billing-agent", "support-bot"];
if (path === "/lens/activity/available") return { traces: true, requests: false };
return { data: [] };
});
vi.mocked(apiClient.post).mockResolvedValue(lens);
const user = userEvent.setup();
renderWithProviders(<InvestigationsView accessToken="test" />);
await user.click(await screen.findByRole("button", { name: "Run now" }));
const dialog = within(await screen.findByRole("dialog", { name: "Run now" }));
await user.click(dialog.getByRole("combobox", { name: "Agent" }));
expect(await screen.findByRole("option", { name: "support-bot" })).toBeVisible();
await user.click(await screen.findByRole("option", { name: "billing-agent" }));
expect(dialog.getByRole("combobox", { name: "Agent" })).toHaveValue("billing-agent");
await user.click(dialog.getByRole("button", { name: "Run now" }));
expect(apiClient.post).toHaveBeenCalledWith("/lens/lens/runs", {
accessToken: "test",
body: { agent_name: "billing-agent" },
});
});
it("offers the interactive demo without starting an investigation", async () => {
window.history.replaceState({}, "", "/lens/");
testQueryClient.clear();

View file

@ -3,6 +3,14 @@
import { useState } from "react";
import { Button } from "@/components/ui/button";
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
} from "@/components/ui/combobox";
import {
Dialog,
DialogContent,
@ -93,18 +101,25 @@ export function RunNowDialog({
<div className="space-y-4">
<label className="grid gap-1.5 text-sm font-medium">
Agent
<Input
list="run-now-agents"
value={agent}
placeholder="All agents"
onChange={(e) => setAgent(e.target.value)}
aria-label="Agent"
/>
<datalist id="run-now-agents">
{agents.map((name) => (
<option key={name} value={name} />
))}
</datalist>
<Combobox
items={agents}
value={agent || null}
inputValue={agent}
onInputValueChange={setAgent}
onValueChange={(name) => setAgent(name ?? "")}
>
<ComboboxInput aria-label="Agent" placeholder="All agents" showClear={!!agent} className="h-9 w-full" />
<ComboboxContent>
<ComboboxEmpty>No matches. You can enter a recorded name.</ComboboxEmpty>
<ComboboxList>
{(name: string) => (
<ComboboxItem key={name} value={name}>
{name}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
</label>
<fieldset className="space-y-2">
<legend className="text-sm font-medium">Traces to review</legend>