Skip to content

Commit 98faa14

Browse files
committed
Merge branch 'main' into nimar/lfe-5387-message-placeholder-python
2 parents 0c7ec1d + 37b2bb2 commit 98faa14

4 files changed

Lines changed: 624 additions & 5 deletions

File tree

langfuse/model.py

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,75 @@ def get_langchain_prompt(self):
173173

174174
@staticmethod
175175
def _get_langchain_prompt_string(content: str):
176-
return re.sub(r"{{\s*(\w+)\s*}}", r"{\g<1>}", content)
176+
json_escaped_content = BasePromptClient._escape_json_for_langchain(content)
177+
178+
return re.sub(r"{{\s*(\w+)\s*}}", r"{\g<1>}", json_escaped_content)
179+
180+
@staticmethod
181+
def _escape_json_for_langchain(text: str) -> str:
182+
"""Escapes every curly-brace that is part of a JSON object by doubling it.
183+
184+
A curly brace is considered “JSON-related” when, after skipping any
185+
immediate whitespace, the next non-whitespace character is a single
186+
or double quote.
187+
188+
Braces that are already doubled (e.g. {{variable}} placeholders) are
189+
left untouched.
190+
191+
Parameters
192+
----------
193+
text : str
194+
The input string that may contain JSON snippets.
195+
196+
Returns:
197+
-------
198+
str
199+
The string with JSON-related braces doubled.
200+
"""
201+
out = [] # collected characters
202+
stack = [] # True = “this { belongs to JSON”, False = normal “{”
203+
i, n = 0, len(text)
204+
205+
while i < n:
206+
ch = text[i]
207+
208+
# ---------- opening brace ----------
209+
if ch == "{":
210+
# leave existing “{{ …” untouched
211+
if i + 1 < n and text[i + 1] == "{":
212+
out.append("{{")
213+
i += 2
214+
continue
215+
216+
# look ahead to find the next non-space character
217+
j = i + 1
218+
while j < n and text[j].isspace():
219+
j += 1
220+
221+
is_json = j < n and text[j] in {"'", '"'}
222+
out.append("{{" if is_json else "{")
223+
stack.append(is_json) # remember how this “{” was treated
224+
i += 1
225+
continue
226+
227+
# ---------- closing brace ----------
228+
elif ch == "}":
229+
# leave existing “… }}” untouched
230+
if i + 1 < n and text[i + 1] == "}":
231+
out.append("}}")
232+
i += 2
233+
continue
234+
235+
is_json = stack.pop() if stack else False
236+
out.append("}}" if is_json else "}")
237+
i += 1
238+
continue
239+
240+
# ---------- any other character ----------
241+
out.append(ch)
242+
i += 1
243+
244+
return "".join(out)
177245

178246

179247
class TextPromptClient(BasePromptClient):

langfuse/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""@private"""
22

3-
__version__ = "3.0.5"
3+
__version__ = "3.0.6"

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[tool.poetry]
22
name = "langfuse"
33

4-
version = "3.0.5"
4+
version = "3.0.6"
55
description = "A client library for accessing langfuse"
66
authors = ["langfuse <developers@langfuse.com>"]
77
license = "MIT"

0 commit comments

Comments
 (0)