From 349d0af5ebb95b2cd5345a29a57429f1b8ed9b11 Mon Sep 17 00:00:00 2001 From: Jared Wein Date: Mon, 29 Jun 2026 15:03:52 -0400 Subject: [PATCH] Pre-fill agent run form from URL query parameters Deep-link support for the agent run page: TriggerForm seeds each field from snake_case query params (agent, bug_id, bug_data, model, max_turns, effort) via useSearchParams, matching the /api/runs inputs contract so a link mirrors what the run receives. Invalid/missing params fall back to the existing empty defaults; an invalid agent falls back to bug-fix. Wrap TriggerForm in a Suspense boundary as required by useSearchParams in Next 15. --- services/hackbot-ui/app/page.tsx | 6 +++- .../hackbot-ui/components/TriggerForm.tsx | 35 +++++++++++++------ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/services/hackbot-ui/app/page.tsx b/services/hackbot-ui/app/page.tsx index bd79a58d3d..bc2183bbb0 100644 --- a/services/hackbot-ui/app/page.tsx +++ b/services/hackbot-ui/app/page.tsx @@ -1,3 +1,5 @@ +import { Suspense } from "react"; + import { RecentRuns } from "@/components/RecentRuns"; import { TriggerForm } from "@/components/TriggerForm"; @@ -6,7 +8,9 @@ export default function HomePage() { <>

Trigger a run

- + + +
diff --git a/services/hackbot-ui/components/TriggerForm.tsx b/services/hackbot-ui/components/TriggerForm.tsx index 9bb145ca77..a8ae657bb1 100644 --- a/services/hackbot-ui/components/TriggerForm.tsx +++ b/services/hackbot-ui/components/TriggerForm.tsx @@ -1,6 +1,6 @@ "use client"; -import { useRouter } from "next/navigation"; +import { useRouter, useSearchParams } from "next/navigation"; import { useState } from "react"; import { saveRun } from "@/lib/store"; @@ -15,17 +15,32 @@ const AGENTS = [ type AgentValue = (typeof AGENTS)[number]["value"]; +function parseAgent(value: string | null): AgentValue { + return AGENTS.some((a) => a.value === value) + ? (value as AgentValue) + : "bug-fix"; +} + export function TriggerForm() { const router = useRouter(); - const [agent, setAgent] = useState("bug-fix"); - const [bugId, setBugId] = useState(""); - const [bugData, setBugData] = useState(""); - const [gitCommit, setGitCommit] = useState(""); - const [failureTasks, setFailureTasks] = useState(""); - const [runTryPush, setRunTryPush] = useState(false); - const [model, setModel] = useState(""); - const [maxTurns, setMaxTurns] = useState(""); - const [effort, setEffort] = useState(""); + const params = useSearchParams(); + const [agent, setAgent] = useState(() => + parseAgent(params.get("agent")) + ); + const [bugId, setBugId] = useState(() => params.get("bug_id") ?? ""); + const [bugData, setBugData] = useState(() => params.get("bug_data") ?? ""); + const [gitCommit, setGitCommit] = useState( + () => params.get("git_commit") ?? "" + ); + const [failureTasks, setFailureTasks] = useState( + () => params.get("failure_tasks") ?? "" + ); + const [runTryPush, setRunTryPush] = useState( + () => params.get("run_try_push") === "true" + ); + const [model, setModel] = useState(() => params.get("model") ?? ""); + const [maxTurns, setMaxTurns] = useState(() => params.get("max_turns") ?? ""); + const [effort, setEffort] = useState(() => params.get("effort") ?? ""); const [submitting, setSubmitting] = useState(false); const [error, setError] = useState(null);