You've already forked adk-python
mirror of
https://github.com/encounter/adk-python.git
synced 2026-03-30 10:57:20 -07:00
fix: Support escaped curly braces in instruction templates
Close #3527 Co-authored-by: George Weale <gweale@google.com> PiperOrigin-RevId: 868875061
This commit is contained in:
committed by
Copybara-Service
parent
34da2d5b26
commit
079f7a38be
@@ -79,16 +79,7 @@ async def inject_session_state(
|
||||
return ''.join(result)
|
||||
|
||||
async def _replace_match(match) -> str:
|
||||
matched_text = match.group()
|
||||
if matched_text.startswith('{{') and matched_text.endswith('}}'):
|
||||
# Preserve escaped non-placeholder literals (e.g. JSON snippets),
|
||||
# but keep escaped placeholders as literal placeholders.
|
||||
escaped_value = matched_text[2:-2]
|
||||
if _is_escaped_placeholder(escaped_value):
|
||||
return matched_text[1:-1]
|
||||
return matched_text
|
||||
|
||||
var_name = matched_text.lstrip('{').rstrip('}').strip()
|
||||
var_name = match.group().lstrip('{').rstrip('}').strip()
|
||||
optional = False
|
||||
if var_name.endswith('?'):
|
||||
optional = True
|
||||
@@ -133,21 +124,6 @@ async def inject_session_state(
|
||||
return await _async_sub(r'{+[^{}]*}+', _replace_match, template)
|
||||
|
||||
|
||||
def _is_escaped_placeholder(value: str) -> bool:
|
||||
"""Checks if escaped braces contain a supported placeholder pattern."""
|
||||
var_name = value.strip()
|
||||
if not var_name:
|
||||
return False
|
||||
|
||||
if var_name.endswith('?'):
|
||||
var_name = var_name.removesuffix('?')
|
||||
|
||||
if var_name.startswith('artifact.'):
|
||||
return True
|
||||
|
||||
return _is_valid_state_name(var_name)
|
||||
|
||||
|
||||
def _is_valid_state_name(var_name):
|
||||
"""Checks if the variable name is a valid state name.
|
||||
|
||||
|
||||
@@ -146,32 +146,6 @@ async def test_inject_session_state_with_invalid_state_name_returns_original():
|
||||
assert populated_instruction == "Hello {invalid-key}!"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_inject_session_state_with_escaped_braces_returns_literal():
|
||||
instruction_template = "Code sample: {{user_name}}. Value: {user_name}."
|
||||
invocation_context = await _create_test_readonly_context(
|
||||
state={"user_name": "Foo"}
|
||||
)
|
||||
|
||||
populated_instruction = await instructions_utils.inject_session_state(
|
||||
instruction_template, invocation_context
|
||||
)
|
||||
assert populated_instruction == "Code sample: {user_name}. Value: Foo."
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_inject_session_state_with_escaped_non_placeholder_keeps_double_braces():
|
||||
instruction_template = "Literal template: {{'key2': 'value2'}}."
|
||||
invocation_context = await _create_test_readonly_context(
|
||||
state={"user_name": "Foo"}
|
||||
)
|
||||
|
||||
populated_instruction = await instructions_utils.inject_session_state(
|
||||
instruction_template, invocation_context
|
||||
)
|
||||
assert populated_instruction == "Literal template: {{'key2': 'value2'}}."
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_inject_session_state_with_invalid_prefix_state_name_returns_original():
|
||||
instruction_template = "Hello {invalid:key}!"
|
||||
|
||||
Reference in New Issue
Block a user