Skip to content

Commit fd023bd

Browse files
committed
fix: do not match dollar-brace or escaped patterns in instructions
1 parent 4092a1f commit fd023bd

2 files changed

Lines changed: 44 additions & 1 deletion

File tree

‎core/src/main/java/com/google/adk/utils/InstructionUtils.java‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@
3232
/** Utility methods for handling instruction templates. */
3333
public final class InstructionUtils {
3434

35+
// Braces preceded by '$', '{' or '\' are left alone, so literal ${expression},
36+
// ${{expression}} and \{expression} in instructions are not treated as placeholders.
3537
private static final Pattern INSTRUCTION_PLACEHOLDER_PATTERN =
36-
Pattern.compile("\\{+[^\\{\\}]*\\}+");
38+
Pattern.compile("(?<![\\$\\{\\\\])\\{+[^\\{\\}]*\\}+");
3739

3840
private InstructionUtils() {}
3941

‎core/src/test/java/com/google/adk/utils/InstructionUtilsTest.java‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,45 @@ public void injectSessionState_stateVariableWithInvalidPrefix_returnsPlaceholder
220220

221221
assertThat(result).isEqualTo(template);
222222
}
223+
224+
@Test
225+
public void injectSessionState_dollarBracePattern_returnsTemplateAsIs() {
226+
String template = "The formatString supports interpolation via ${expression} syntax.";
227+
228+
String result = InstructionUtils.injectSessionState(templateContext, template).blockingGet();
229+
230+
assertThat(result).isEqualTo(template);
231+
}
232+
233+
@Test
234+
public void injectSessionState_dollarBracePatternWithStateVariable_replacesOnlyStateVariable() {
235+
InvocationContext testContext = templateContext.toBuilder().build();
236+
testContext.session().state().put("user_name", "Foo");
237+
String template = "Hello {user_name}! Interpolation via ${expression} syntax.";
238+
239+
String result = InstructionUtils.injectSessionState(testContext, template).blockingGet();
240+
241+
assertThat(result).isEqualTo("Hello Foo! Interpolation via ${expression} syntax.");
242+
}
243+
244+
@Test
245+
public void injectSessionState_escapedBraces_returnsTemplateAsIs() {
246+
String template = "Literal \\{expression\\} syntax.";
247+
248+
String result = InstructionUtils.injectSessionState(templateContext, template).blockingGet();
249+
250+
assertThat(result).isEqualTo(template);
251+
}
252+
253+
@Test
254+
public void injectSessionState_dollarDoubleBracePattern_returnsPatternAsIs() {
255+
InvocationContext testContext = templateContext.toBuilder().build();
256+
testContext.session().state().put("expression", "foo");
257+
testContext.session().state().put("user_name", "bar");
258+
String template = "Workflow syntax: ${{expression}} and {user_name}.";
259+
260+
String result = InstructionUtils.injectSessionState(testContext, template).blockingGet();
261+
262+
assertThat(result).isEqualTo("Workflow syntax: ${{expression}} and bar.");
263+
}
223264
}

0 commit comments

Comments
 (0)