You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat: Add a way to skip context variable interpolation/injection. #5179
Is your feature request related to a specific problem?
Yes, I'm unable to include the string ${<expression>} in my prompt. The interpolation code wants to expand it to the contents of a context key <expression> and remove the curly braces.
Describe the Solution You'd Like
I'd like a way to turn off or escape curly brace expressions in prompt strings.
Impact on your work
I'm working on something that requires describing the output format I'd like the LLM to produce, and part of that format includes curly braces. I have had to monkey-patch the ADK in order to get the functionality I need.
Willingness to contribute
I would be willing to contribute a PR, although I don't have one prepared.
Describe Alternatives You've Considered
I've tried escaping the curly braces with backslashes, doubling them, and including the the key "<expression>" = "{<expression>}" in the context, but escaping didn't work, and including the contents of every curly brace in the context isn't scalable.
Proposed API / Implementation
Option 1: Support Escaping via Double Braces
Adopt the Python standard (used in str.format) where double braces {{ and }} are resolved to literal { and } and ignored by the parser.
Option 2: Allow Custom Delimiters
Allow users to specify custom delimiters for templates to avoid collisions with the target template's syntax.
@gspencergoog Thanks for the update. The request is currently being reviewed by our team, and I will let you know if anything further is needed. Thank you for understanding.
1. Escaping — the template scanner (_TEMPLATE_VAR_PATTERN in google/adk/flows/llm_flows/prompt/_instructions_utils.py) uses a negative lookbehind (?<![\$\{\\]), so a brace expression preceded by $ or \ is never interpolated. Your exact case works as-is:
Input
Output
Use ${expression} literally.
Use ${expression} literally.
Use \{expression} literally.
Use \{expression} literally.
Return JSON like {"a": 1, "b": [2]}.
unchanged — non-identifier content is left literal
2. Custom delimiters (your Option 2) — pass use_jinja2=True to inject_session_state(...). Jinja2 only treats {{ ... }} as a variable, so every single-brace expression in the prompt stays literal:
Activity
klateefa commentedon Apr 8, 2026
@gspencergoog Thanks for the update. The request is currently being reviewed by our team, and I will let you know if anything further is needed. Thank you for understanding.
ditman commentedon May 22, 2026
May be fixed by: #5711 ?
DeanChensj commentedon Sep 21, 2026
This is supported today on the current release.
1. Escaping — the template scanner (
_TEMPLATE_VAR_PATTERNingoogle/adk/flows/llm_flows/prompt/_instructions_utils.py) uses a negative lookbehind(?<![\$\{\\]), so a brace expression preceded by$or\is never interpolated. Your exact case works as-is:Use ${expression} literally.Use ${expression} literally.Use \{expression} literally.Use \{expression} literally.Return JSON like {"a": 1, "b": [2]}.2. Custom delimiters (your Option 2) — pass
use_jinja2=Truetoinject_session_state(...). Jinja2 only treats{{ ... }}as a variable, so every single-brace expression in the prompt stays literal:Verified against the current source. Closing as supported — please reopen if you have a case that is still being interpolated.