Skip to content

Commit 8cb5fd8

Browse files
kathiekiwiTrigger.dev RepoOps
authored andcommitted
fix(webapp): keep agent-suggested threshold and window in query alert prefill
Query alerts suggested by the dashboard agent now open with the suggested threshold and time window prefilled. Mono-RevId: 9a125338c2eddb048059949b2161432590941234
1 parent 5a1c142 commit 8cb5fd8

7 files changed

Lines changed: 47 additions & 2 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
area: webapp
3+
type: fix
4+
---
5+
6+
Fix the dashboard agent's suggested threshold and window being dropped when it prefills a query alert.

‎apps/webapp/app/components/alerts/QueryAlertTranscript.dom.test.ts‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,19 @@ describe("QueryAlertTranscript", () => {
333333
choose("For 24 hours");
334334
}
335335

336+
it("keeps the agent-suggested threshold and window", async () => {
337+
await mount({ operator: ">", value: 42, windowSec: 601 });
338+
choose("Continue");
339+
choose("Value crosses a threshold");
340+
expect(input("Threshold").value).toBe("42");
341+
expect(row("Above").querySelector('[aria-label="Selected"]')).not.toBeNull();
342+
expect(
343+
document.querySelector<HTMLButtonElement>('button[aria-label="Next question"]')!.disabled
344+
).toBe(false);
345+
choose("Above");
346+
expect(input("Window").value).toBe("11");
347+
});
348+
336349
it("offers This chat in the agent, preselected, and sends the chat ids", async () => {
337350
const release = vi.fn();
338351
await mount({}, { chatId: "chat_on_use", ensure: async () => ({ chatId: "chat_1", release }) });

‎apps/webapp/app/components/alerts/QueryAlertTranscript.tsx‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ export type QueryWatchPrefill = {
3939
mode?: QueryAlertMode;
4040
measure?: string;
4141
operator?: ">" | "<";
42+
value?: number;
43+
windowSec?: number;
4244
};
4345

4446
export function queryWatchPrefill(
@@ -105,6 +107,8 @@ export function QueryAlertTranscript({
105107
mode: prefill.mode,
106108
measure: prefill.measure,
107109
operator: prefill.operator,
110+
value: prefill.value,
111+
windowSec: prefill.windowSec,
108112
...analyzed,
109113
}
110114
: undefined;

‎apps/webapp/app/components/alerts/queryAlertLink.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export type QueryAlertPrefill = {
1818
mode?: QueryAlertMode;
1919
measure?: string;
2020
operator?: ">" | "<";
21+
value?: number;
22+
windowSec?: number;
2123
};
2224

2325
export function queryAlertNameKey(mode: QueryAlertMode, measure?: string) {

‎apps/webapp/app/components/alerts/useQueryAlertDraft.ts‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,19 @@ export function useQueryAlertDraft(
5656
const measure = mode === "match" ? undefined : signal.measure;
5757

5858
const [operator, setOperator] = useState<">" | "<">(prefill.operator ?? ">");
59-
const [valueText, setValueText] = useState("");
59+
const [valueText, setValueText] = useState(() =>
60+
typeof prefill.value === "number" && Number.isFinite(prefill.value) ? String(prefill.value) : ""
61+
);
6062
const value = valueText.trim() === "" ? undefined : Number(valueText);
6163
const valueValid = mode !== "threshold" || (value !== undefined && Number.isFinite(value));
6264

6365
const bounds = queryWindowBounds(analysis.limits);
6466
const defaultWindow = defaultQueryWindowMinutes(prefill.period, analysis.limits);
65-
const [windowText, setWindowText] = useState(() => String(defaultWindow));
67+
const [windowText, setWindowText] = useState(() => {
68+
const windowSec = prefill.windowSec;
69+
if (typeof windowSec !== "number" || !Number.isFinite(windowSec)) return String(defaultWindow);
70+
return String(Math.min(bounds.max, Math.max(bounds.min, Math.ceil(windowSec / 60))));
71+
});
6672
const windowMinutes = mode === "match" ? defaultWindow : Number(windowText);
6773
const windowValid =
6874
mode === "match" ||

‎apps/webapp/app/components/dashboard-agent/alert-creation/draftPatch.test.ts‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
alertDraftPatchSchema,
1414
applyDraftPatch,
1515
errorGroupToResolve,
16+
queryWatchFromPatch,
1617
type AlertDraftPatch,
1718
} from "./draftPatch";
1819
import { draftResultLines } from "./useCreationAgentSend";
@@ -267,6 +268,17 @@ describe("below-threshold operator", () => {
267268
});
268269
});
269270

271+
describe("queryWatchFromPatch", () => {
272+
it("carries the threshold value and window", () => {
273+
const patch = {
274+
area: "query",
275+
query: "SELECT 1",
276+
condition: { operator: ">", value: 42, windowSec: 601 },
277+
} as AlertDraftPatch;
278+
expect(queryWatchFromPatch(patch)).toMatchObject({ operator: ">", value: 42, windowSec: 601 });
279+
});
280+
});
281+
270282
describe("unknown-key rejection", () => {
271283
it("fails when a patch with an unknown key is applied client-side without rejection", () => {
272284
const result = alertDraftPatchSchema.safeParse({

‎apps/webapp/app/components/dashboard-agent/alert-creation/draftPatch.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ export function queryWatchFromPatch(patch: AlertDraftPatch): QueryWatchPrefill |
6767
mode: patch.querySignalChoice?.mode,
6868
measure: patch.querySignalChoice?.measure,
6969
operator: patch.condition?.operator,
70+
value: patch.condition?.value,
71+
windowSec: patch.condition?.windowSec,
7072
};
7173
}
7274

0 commit comments

Comments
 (0)