Skip to content

Commit 018a22e

Browse files
committed
fix(langchain): escape empty json braces in prompts
1 parent 8c8b120 commit 018a22e

2 files changed

Lines changed: 39 additions & 2 deletions

File tree

langfuse/model.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ def _escape_json_for_langchain(text: str) -> str:
171171
172172
A curly brace is considered “JSON-related” when, after skipping any
173173
immediate whitespace, the next non-whitespace character is a single
174-
or double quote.
174+
quote, double quote, or the matching closing brace of an empty object.
175175
176176
Braces that are already doubled (e.g. {{variable}} placeholders) are
177177
left untouched.
@@ -206,7 +206,7 @@ def _escape_json_for_langchain(text: str) -> str:
206206
while j < n and text[j].isspace():
207207
j += 1
208208

209-
is_json = j < n and text[j] in {"'", '"'}
209+
is_json = j < n and text[j] in {"'", '"', "}"}
210210
out.append("{{" if is_json else "{")
211211
stack.append(is_json) # remember how this “{” was treated
212212
i += 1

tests/unit/test_prompt_compilation.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,43 @@ def test_edge_case_empty_json_objects(self):
449449

450450
assert formatted_prompt == expected
451451

452+
def test_langchain_prompt_escapes_bare_empty_json_objects(self):
453+
"""Test that bare empty JSON objects remain literals in LangChain prompts."""
454+
prompt_string = """Variable: {{test_var}}
455+
Empty object: {}
456+
Spaced empty object: { }
457+
Multiline empty object: {
458+
}
459+
LangChain variable: {langchain_var}"""
460+
461+
prompt = TextPromptClient(
462+
Prompt_Text(
463+
type="text",
464+
name="bare_empty_json_test",
465+
version=1,
466+
config={},
467+
tags=[],
468+
labels=[],
469+
prompt=prompt_string,
470+
)
471+
)
472+
473+
langchain_prompt_string = prompt.get_langchain_prompt()
474+
langchain_prompt = PromptTemplate.from_template(langchain_prompt_string)
475+
formatted_prompt = langchain_prompt.format(
476+
test_var="value",
477+
langchain_var="chain",
478+
)
479+
480+
expected = """Variable: value
481+
Empty object: {}
482+
Spaced empty object: { }
483+
Multiline empty object: {
484+
}
485+
LangChain variable: chain"""
486+
487+
assert formatted_prompt == expected
488+
452489
def test_edge_case_nested_quotes_in_json(self):
453490
"""Test edge case with nested quotes and escaped characters in JSON."""
454491
prompt_string = """Message: {{message}}

0 commit comments

Comments
 (0)