frontend support browser header (#2761)

This commit is contained in:
Shuchang Zheng
2025-06-21 08:50:19 +08:00
committed by GitHub
parent 592ed941ce
commit 1bf270df55
20 changed files with 495 additions and 0 deletions

View File

@@ -17,6 +17,7 @@ import {
import { Input } from "@/components/ui/input";
import { Separator } from "@/components/ui/separator";
import { toast } from "@/components/ui/use-toast";
import { KeyValueInput } from "@/components/KeyValueInput";
import { useApiCredential } from "@/hooks/useApiCredential";
import { useCredentialGetter } from "@/hooks/useCredentialGetter";
import { CodeEditor } from "@/routes/workflows/components/CodeEditor";
@@ -61,6 +62,14 @@ function createTaskRequestObject(
extractedInformationSchema = formValues.extractedInformationSchema;
}
}
let extraHttpHeaders = null;
if (formValues.extraHttpHeaders) {
try {
extraHttpHeaders = JSON.parse(formValues.extraHttpHeaders);
} catch (e) {
extraHttpHeaders = formValues.extraHttpHeaders;
}
}
let errorCodeMapping = null;
if (formValues.errorCodeMapping) {
try {
@@ -79,6 +88,7 @@ function createTaskRequestObject(
proxy_location: formValues.proxyLocation ?? ProxyLocation.Residential,
navigation_payload: transform(formValues.navigationPayload),
extracted_information_schema: extractedInformationSchema,
extra_http_headers: extraHttpHeaders,
totp_identifier: transform(formValues.totpIdentifier),
error_code_mapping: errorCodeMapping,
max_screenshot_scrolling_times: formValues.maxScreenshotScrollingTimes,
@@ -601,6 +611,35 @@ function CreateNewTaskForm({ initialValues }: Props) {
)}
/>
<Separator />
<FormField
control={form.control}
name="extraHttpHeaders"
render={({ field }) => (
<FormItem>
<div className="flex gap-16">
<FormLabel>
<div className="w-72">
<h1 className="text-lg">Extra HTTP Headers</h1>
<h2 className="text-base text-slate-400">
Specify some self defined HTTP requests headers in
Dict format
</h2>
</div>
</FormLabel>
<div className="w-full">
<FormControl>
<KeyValueInput
value={field.value ?? ""}
onChange={(val) => field.onChange(val)}
addButtonText="Add Header"
/>
</FormControl>
<FormMessage />
</div>
</div>
</FormItem>
)}
/>
<FormField
control={form.control}
name="errorCodeMapping"

View File

@@ -63,6 +63,7 @@ function CreateNewTaskFormPage() {
proxyLocation: null,
includeActionHistoryInVerification: null,
maxScreenshotScrollingTimes: null,
extraHttpHeaders: null,
}}
/>
</div>
@@ -133,6 +134,9 @@ function CreateNewTaskFormPage() {
data.workflow_definition.blocks[0]
.include_action_history_in_verification,
maxScreenshotScrollingTimes: data.max_screenshot_scrolling_times,
extraHttpHeaders: data.extra_http_headers
? JSON.stringify(data.extra_http_headers)
: null,
}}
/>
</div>

View File

@@ -14,6 +14,7 @@ import { MessageIcon } from "@/components/icons/MessageIcon";
import { TrophyIcon } from "@/components/icons/TrophyIcon";
import { ProxySelector } from "@/components/ProxySelector";
import { Input } from "@/components/ui/input";
import { KeyValueInput } from "@/components/KeyValueInput";
import {
CustomSelectItem,
Select,
@@ -161,6 +162,7 @@ function PromptBox() {
useState<string | null>(null);
const [showAdvancedSettings, setShowAdvancedSettings] = useState(false);
const [dataSchema, setDataSchema] = useState<string | null>(null);
const [extraHttpHeaders, setExtraHttpHeaders] = useState<string | null>(null);
const startObserverCruiseMutation = useMutation({
mutationFn: async (prompt: string) => {
@@ -184,6 +186,15 @@ function PromptBox() {
}
})()
: null,
extra_http_headers: extraHttpHeaders
? (() => {
try {
return JSON.parse(extraHttpHeaders);
} catch (e) {
return extraHttpHeaders;
}
})()
: null,
},
{
headers: {
@@ -414,6 +425,30 @@ function PromptBox() {
}}
/>
</div>
<div className="flex gap-16">
<div className="w-48 shrink-0">
<div className="text-sm">Extra HTTP Headers</div>
<div className="text-xs text-slate-400">
Specify some self defined HTTP requests headers in Dict
format
</div>
</div>
<div className="flex-1">
<KeyValueInput
value={extraHttpHeaders ?? ""}
onChange={(val) =>
setExtraHttpHeaders(
val === null
? null
: typeof val === "string"
? val || null
: JSON.stringify(val),
)
}
addButtonText="Add Header"
/>
</div>
</div>
<div className="flex gap-16">
<div className="w-48 shrink-0">
<div className="text-sm">Publish Workflow</div>

View File

@@ -46,6 +46,9 @@ function RetryTask() {
task.request.include_action_history_in_verification ?? false,
maxScreenshotScrollingTimes:
task.request.max_screenshot_scrolling_times ?? null,
extraHttpHeaders: task.request.extra_http_headers
? JSON.stringify(task.request.extra_http_headers)
: null,
}}
/>
</div>

View File

@@ -10,6 +10,7 @@ const createNewTaskFormSchemaBase = z.object({
dataExtractionGoal: z.string().or(z.null()),
navigationPayload: z.string().or(z.null()),
extractedInformationSchema: z.string().or(z.null()),
extraHttpHeaders: z.string().or(z.null()),
maxStepsOverride: z.number().or(z.null()).optional(),
totpIdentifier: z.string().or(z.null()),
errorCodeMapping: z.string().or(z.null()),

View File

@@ -1,11 +1,13 @@
import { getClient } from "@/api/AxiosClient";
import { TaskApiResponse } from "@/api/types";
import { AutoResizingTextarea } from "@/components/AutoResizingTextarea/AutoResizingTextarea";
import { KeyValueInput } from "@/components/KeyValueInput";
import { Input } from "@/components/ui/input";
import { Skeleton } from "@/components/ui/skeleton";
import { Switch } from "@/components/ui/switch";
import { useCredentialGetter } from "@/hooks/useCredentialGetter";
import { CodeEditor } from "@/routes/workflows/components/CodeEditor";
import { MAX_SCREENSHOT_SCROLLING_TIMES_DEFAULT } from "@/routes/workflows/editor/nodes/Taskv2Node/types";
import { useQuery } from "@tanstack/react-query";
import { useParams } from "react-router-dom";
@@ -115,6 +117,25 @@ function TaskParameters() {
maxHeight="500px"
/>
</div>
<div className="flex gap-16">
<div className="w-72">
<h1 className="text-lg">Extra HTTP Headers</h1>
<h2 className="text-base text-slate-400">
Specify some self defined HTTP requests headers in Dict format
</h2>
</div>
<div className="w-full">
<KeyValueInput
value={
task.request.extra_http_headers
? JSON.stringify(task.request.extra_http_headers)
: null
}
readOnly={true}
onChange={() => {}}
/>
</div>
</div>
<div className="flex gap-16">
<div className="w-72">
<h1 className="text-lg">Webhook Callback URL</h1>
@@ -124,6 +145,19 @@ function TaskParameters() {
</div>
<Input value={task.request.webhook_callback_url ?? ""} readOnly />
</div>
<div className="flex gap-16">
<div className="w-72">
<h1 className="text-lg">Max Scrolling Screenshots</h1>
<h2 className="text-base text-slate-400">
The maximum number of times to scroll the page
</h2>
</div>
<Input
placeholder={`Default: ${MAX_SCREENSHOT_SCROLLING_TIMES_DEFAULT}`}
value={task.request.max_screenshot_scrolling_times ?? ""}
readOnly
/>
</div>
<div className="flex gap-16">
<div className="w-72">
<h1 className="text-lg">Include Action History</h1>