From ed01ac999408fd3b3109785eacbbf430d3bf039f Mon Sep 17 00:00:00 2001 From: Tim Wang <38489718+wanghualoong@users.noreply.github.com> Date: Mon, 11 May 2026 10:01:41 +0800 Subject: [PATCH] Fix: resolve template strings in tool component parameters (#14601) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Tool-type components (Email, Invoke, etc.) fail to resolve template strings that mix variable references with literal text in their parameters. - This adds template string resolution to `get_input()` in `ComponentBase`, reusing existing `get_input_elements_from_text()` and `string_format()` methods. ## Problem `get_input()` in `ComponentBase` handles two cases: 1. **Pure reference** (`{Component:ID@field}`) — resolved via `is_reff()` + `get_variable_value()` 2. **Literal value** — passed through as-is But template strings like `{UserFillUp:X@name}@duke.edu` or `Question from {Agent:Y@topic}` fall through to the literal branch because `is_reff()` returns `False` (it expects the entire string to be a single reference). The unresolved template is passed directly to the tool. This affects **all** tool components (Email, Invoke, etc.) that need mixed reference + text parameters — for example, constructing email addresses or subjects dynamically. ## Fix ```python # In get_input(), between is_reff check and literal fallback: elif isinstance(v, str) and re.search(self.variable_ref_patt, v): elements = self.get_input_elements_from_text(v) kv = {k: e.get('value', '') for k, e in elements.items()} self.set_input_value(var, self.string_format(v, kv)) ``` This reuses `get_input_elements_from_text()` and `string_format()` which are already used by `Message` components for the same purpose. The fix only activates when the string contains at least one variable reference pattern but is not a pure reference. ## Test plan - [x] Pure references (`{Component:ID@field}`) still resolve correctly via `is_reff()` path - [x] Literal values without references pass through unchanged - [x] Template strings like `{ref}@duke.edu` resolve the reference and keep the literal suffix - [x] Template strings like `Question from {ref}` resolve correctly - [x] Multiple references in one string (`{ref1} and {ref2}`) both resolve - [x] Message components unaffected (they use their own template resolution in `_run`) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: wanghualoong Co-authored-by: Claude Opus 4.6 --- agent/component/base.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/agent/component/base.py b/agent/component/base.py index 9bceb4ce6..1acfa773d 100644 --- a/agent/component/base.py +++ b/agent/component/base.py @@ -486,6 +486,10 @@ class ComponentBase(ABC): continue if isinstance(v, str) and self._canvas.is_reff(v): self.set_input_value(var, self._canvas.get_variable_value(v)) + elif isinstance(v, str) and re.search(self.variable_ref_patt, v): + elements = self.get_input_elements_from_text(v) + kv = {k: e.get('value', '') for k, e in elements.items()} + self.set_input_value(var, self.string_format(v, kv)) else: self.set_input_value(var, v) res[var] = self.get_input_value(var)