feat: support {{variable}} substitution in HTTP tool endpoint URL

Apply the same render_template() logic used for node prompts and preset
parameters to the endpoint URL, so users can use {{initial_context.*}}
and {{gathered_context.*}} in the URL path. The URL is rendered at
execution time just before the HTTP request.

- Backend: render URL via render_template() in execute_http_tool
- Frontend: allow {{variable}} in URL path but reject in domain
- Frontend: add hint label below Endpoint URL field
- Tests: verify URL rendering with initial_context, gathered_context,
  and static (unchanged) URLs
This commit is contained in:
XI 2026-06-03 02:35:43 +01:00
parent 2326a2f65a
commit 49fcb770a4
4 changed files with 142 additions and 0 deletions

View file

@ -141,6 +141,9 @@ export function HttpApiToolConfig({
<div className="grid gap-2">
<Label>Endpoint URL</Label>
<Label className="text-xs text-muted-foreground">
Supports {`{{variable}}`} syntax using initial and gathered context variables in the URL path
</Label>
<UrlInput
value={url}
onChange={onUrlChange}

View file

@ -19,6 +19,12 @@ export interface UrlValidationResult {
error?: string;
}
const DOMAIN_REGEX = /^https?:\/\/([^\/]+)/;
function domainContainsTemplateVar(domain: string): boolean {
return domain.includes("{{") || domain.includes("}}");
}
export function validateUrl(url: string): UrlValidationResult {
const trimmedUrl = url.trim();
@ -26,6 +32,18 @@ export function validateUrl(url: string): UrlValidationResult {
return { valid: false, error: "URL is required" };
}
// If the URL contains template variables, validate domain separately
if (trimmedUrl.includes("{{")) {
const domainMatch = trimmedUrl.match(DOMAIN_REGEX);
if (!domainMatch || domainContainsTemplateVar(domainMatch[1])) {
return {
valid: false,
error: "Invalid URL format. Template variables are only allowed in the URL path.",
};
}
return { valid: true };
}
if (!URL_REGEX.test(trimmedUrl)) {
return {
valid: false,