fix(consolidation): escape literal braces in caller-supplied mission text#1676
Open
cdbartholomew wants to merge 3 commits into
Open
fix(consolidation): escape literal braces in caller-supplied mission text#1676cdbartholomew wants to merge 3 commits into
cdbartholomew wants to merge 3 commits into
Conversation
…text
The batch consolidation prompt is assembled from caller-supplied text
(observations_mission, observation_capacity_note) interleaved with
literal {facts_text} / {observations_text} placeholders, then passed
through str.format() at call time. Any { or } in the caller-supplied
text was previously interpreted as a format placeholder and raised
KeyError, taking down consolidation for that bank.
Escape lone braces before assembly so the rendered prompt contains the
original characters verbatim. The escape is idempotent — text that
already contains {{ / }} pairs is left untouched, so callers that
pre-escape for any reason still produce the same rendered output.
Includes regression tests covering JSON-shaped mission text,
pre-escaped input, multiple brace pairs, and the unchanged
substitution path for the real placeholders.
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.
Summary
The batch consolidation prompt is assembled from caller-supplied text (
observations_mission,observation_capacity_note) interleaved with literal{facts_text}/{observations_text}placeholders, then passed throughstr.format()at call time. Any{or}in the caller-supplied text was previously interpreted as a format placeholder and raisedKeyError, taking down consolidation for that bank — for example, a mission containing a JSON example like{"key": value}would crash withKeyError: "'key'".This change escapes lone braces before assembly so the rendered prompt contains the original characters verbatim.
The escape is idempotent: text that already contains
{{/}}pairs is left untouched, so callers that pre-escape (or future call sites that defensively double-escape) still produce the same rendered output.Implementation
prompts.pyadds_escape_braces()which doubles only lone{and}characters, leaving already-doubled pairs alone.observations_missionandobservation_capacity_noteare routed through it before being f-string-interpolated into the assembled prompt.{facts_text},{observations_text}) live in module-level constants that already use{{/}}for any literal JSON in the prompt, so they are unaffected.Tests
17 new tests in
tests/test_consolidation_prompt_brace_escape.py:_escape_bracesunit coverage (lone brace doubling, idempotency, no-op on plain prose, mixed lone + already-escaped input).build_batch_consolidation_prompt:{facts_text}/{observations_text}substitution path still works.{single},}}weird{{, trailing{, leading}, empty string.Test plan
uv run pytest tests/test_consolidation_prompt_brace_escape.py -v→ 17 passeduv run pytest tests/test_consolidation_failure_recovery.py tests/test_consolidation_prompt_brace_escape.py tests/test_format_facts_for_prompt.py→ 30 passed (pre-existing collection errors intest_consolidation_round_limit.pyreproduce on cleanorigin/mainand are unrelated)uv run ruff checkcleanuv run ty check hindsight_api/engine/consolidation/prompts.pyclean