From 66bc5d3e60d5cc005c3d51b9dc9aba0be3364d41 Mon Sep 17 00:00:00 2001 From: XI Date: Wed, 3 Jun 2026 08:46:06 +0100 Subject: [PATCH] feat: support {{variable}} in HTTP tool URL and add variable extraction timing option - Apply render_template() to the endpoint URL at runtime so {{initial_context.*}} and {{gathered_context.*}} work in URL paths (same logic as node prompts and preset parameters). - Update URL validation to allow template variables in the path but reject them in the domain. - Add variable_extraction_timing setting (before/after/both) to HTTP tools, controlling when conversation variable extraction runs relative to the tool call. - Add Variable Extraction Timing radio group to the tool Settings tab with Before/After/Both options. --- .../workflow/pipecat_engine_custom_tools.py | 13 ++++ .../components/HttpApiToolConfig.tsx | 69 +++++++++++++++++++ ui/src/app/tools/[toolUuid]/page.tsx | 7 ++ ui/src/client/types.gen.ts | 6 ++ 4 files changed, 95 insertions(+) diff --git a/api/services/workflow/pipecat_engine_custom_tools.py b/api/services/workflow/pipecat_engine_custom_tools.py index 25298d73..02dd06d4 100644 --- a/api/services/workflow/pipecat_engine_custom_tools.py +++ b/api/services/workflow/pipecat_engine_custom_tools.py @@ -378,6 +378,14 @@ class CustomToolManager: ) ) + # Determine when to run variable extraction relative to the tool call + extraction_timing = config.get("variable_extraction_timing", "before") + + if extraction_timing in ("before", "both"): + await self._engine._perform_variable_extraction_if_needed( + self._engine._current_node, run_in_background=False + ) + result = await execute_http_tool( tool=tool, arguments=function_call_params.arguments, @@ -386,6 +394,11 @@ class CustomToolManager: organization_id=await self.get_organization_id(), ) + if extraction_timing in ("after", "both"): + await self._engine._perform_variable_extraction_if_needed( + self._engine._current_node, run_in_background=False + ) + await function_call_params.result_callback(result) except Exception as e: diff --git a/ui/src/app/tools/[toolUuid]/components/HttpApiToolConfig.tsx b/ui/src/app/tools/[toolUuid]/components/HttpApiToolConfig.tsx index e61f6860..b780bf46 100644 --- a/ui/src/app/tools/[toolUuid]/components/HttpApiToolConfig.tsx +++ b/ui/src/app/tools/[toolUuid]/components/HttpApiToolConfig.tsx @@ -1,5 +1,7 @@ "use client"; +import { AlertCircle, Variable } from "lucide-react"; + import type { RecordingResponseSchema } from "@/client/types.gen"; import { StaticTextWarning, TextOrAudioInput } from "@/components/flow/TextOrAudioInput"; import { @@ -17,6 +19,7 @@ import { import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; +import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Textarea } from "@/components/ui/textarea"; @@ -45,6 +48,8 @@ export interface HttpApiToolConfigProps { onCustomMessageTypeChange: (type: 'text' | 'audio') => void; customMessageRecordingId: string; onCustomMessageRecordingIdChange: (id: string) => void; + variableExtractionTiming: 'before' | 'after' | 'both'; + onVariableExtractionTimingChange: (timing: 'before' | 'after' | 'both') => void; recordings?: RecordingResponseSchema[]; } @@ -73,6 +78,8 @@ export function HttpApiToolConfig({ onCustomMessageTypeChange, customMessageRecordingId, onCustomMessageRecordingIdChange, + variableExtractionTiming, + onVariableExtractionTimingChange, recordings = [], }: HttpApiToolConfigProps) { return ( @@ -152,6 +159,63 @@ export function HttpApiToolConfig({ /> +
+
+ + +
+ + onVariableExtractionTimingChange(v as 'before' | 'after' | 'both')} + > + + + + +
+