fix(prompt): handle escaped braces in f-string variable extraction - #697
Open
anxkhn wants to merge 6 commits into
Open
fix(prompt): handle escaped braces in f-string variable extraction#697anxkhn wants to merge 6 commits into
anxkhn wants to merge 6 commits into
Conversation
extract_fstring_variables used the regex \{([^{}]+)\} to find template
placeholders, which is unaware of str.format escaped braces. In an
f-string/str.format template, {{ and }} are literal { and }, but the
regex matched the text between them as a variable. A template such as
'Respond as JSON like {{"answer": "..."}}. Q: {question}' was reported
as having the variables ['"answer": "..."', 'question'] instead of just
['question'].
This disagreed with render_fstring_template, which calls
template.format(**kwargs) and correctly renders {{ }} as literal braces.
StringPromptTemplate.format_prompt then raised a spurious
"Missing required variables" ValueError, because the phantom variable is
never a valid kwarg. Literal JSON examples in prompts are a very common
pattern, so valid templates were rejected.
Replace the regex with string.Formatter().parse(), which shares
str.format() semantics, so extraction and rendering agree. Escaped
braces are ignored, format specs are dropped ({x:>10} -> 'x'), and
duplicates and attribute/index access are preserved. Add unit tests for
extract_fstring_variables and StringPromptTemplate.format_prompt covering
escaped braces, format specs, and the existing behavior.
Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes f-string/str.format template variable extraction so escaped braces ({{ / }}) are treated as literals (matching str.format semantics), preventing StringPromptTemplate from rejecting valid prompt templates that include literal JSON examples.
Changes:
- Replaced regex-based placeholder extraction with
string.Formatter().parse()inextract_fstring_variables. - Added unit tests covering escaped braces, format specs, duplicates, and extraction/render agreement.
- Added end-to-end tests verifying
StringPromptTemplate.format_promptaccepts escaped-brace templates and still errors on genuinely missing variables.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| dapr_agents/prompt/utils/fstring.py | Switches variable extraction to stdlib Formatter.parse() to properly ignore escaped braces and drop format specs. |
| tests/prompt/utils/test_fstring.py | Adds focused unit coverage for f-string extraction/rendering (including escaped braces). |
| tests/prompt/test_string_prompt.py | Adds E2E coverage for StringPromptTemplate behavior with escaped braces and missing variables. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Sam <sam@diagrid.io>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Notes on the checklist choices (not part of the PR body)
keys + a Dapr sidecar; not run here. This is an internal parsing fix with unit
coverage, so honestly leaving it unchecked is correct.
(docstring/comment on
extract_fstring_variables) and in this PR; the nesteddapr/docsPR box is intentionally left unchecked with an inline N/A becauseAGENTS.md and the repo's PR rules exempt internal-only bug fixes that do not change
the public API / features / config / observable behavior. If a reviewer disagrees,
a two-line note in the f-string prompt docs is the fallback.
Changeset summary (what Anas is approving)
dapr_agents/prompt/utils/fstring.py(+10/-5): dropimport re; extract variableswith
string.Formatter().parse(). Onlyextract_fstring_variableschanges;render_fstring_templateuntouched.tests/prompt/utils/test_fstring.py(new, +85): unit tests for extract + render(escaped braces, format spec, dupes, attr/index, plain text; render/extract agree).
tests/prompt/test_string_prompt.py(new, +50): end-to-endformat_prompttests(escaped-brace template renders; input_variables exclude escaped content; missing
variable still raises).
Verification (re-confirmed at draft time, 2026-07-04):
uv run --no-sync ruff format --check(3 changed files) -> "3 files already formatted".uv run --no-sync flake8 ... --ignore=E501,F401,W503,E203,E704-> exit 0.pytest tests/prompt/utils/test_fstring.py tests/prompt/test_string_prompt.py-> 14 passed.
pytest tests -m "not integration"-> 952 passed / 15 skipped / 0 failed, andindependently proved red->green (revert fstring.py only -> exactly 6 targeted tests fail).