@@ -141,6 +141,161 @@ def test_create_chat_prompt_with_placeholders():
141141 assert prompt_client .config == {}
142142
143143
144+ def test_create_prompt_with_placeholders ():
145+ """Test creating a prompt with placeholder messages."""
146+ langfuse = Langfuse ()
147+ prompt_name = create_uuid ()
148+ prompt_client = langfuse .create_prompt (
149+ name = prompt_name ,
150+ prompt = [
151+ {"role" : "system" , "content" : "System message" },
152+ {"type" : "placeholder" , "name" : "context" },
153+ {"role" : "user" , "content" : "User message" },
154+ ],
155+ type = "chat" ,
156+ )
157+
158+ # Verify the full prompt structure with placeholders
159+ assert len (prompt_client .prompt ) == 3
160+
161+ # First message - system
162+ assert prompt_client .prompt [0 ]["type" ] == "message"
163+ assert prompt_client .prompt [0 ]["role" ] == "system"
164+ assert prompt_client .prompt [0 ]["content" ] == "System message"
165+ # Placeholder
166+ assert prompt_client .prompt [1 ]["type" ] == "placeholder"
167+ assert prompt_client .prompt [1 ]["name" ] == "context"
168+ # Third message - user
169+ assert prompt_client .prompt [2 ]["type" ] == "message"
170+ assert prompt_client .prompt [2 ]["role" ] == "user"
171+ assert prompt_client .prompt [2 ]["content" ] == "User message"
172+
173+
174+ def test_get_prompt_with_placeholders ():
175+ """Test retrieving a prompt with placeholders."""
176+ langfuse = Langfuse ()
177+ prompt_name = create_uuid ()
178+
179+ langfuse .create_prompt (
180+ name = prompt_name ,
181+ prompt = [
182+ {"role" : "system" , "content" : "You are {{name}}" },
183+ {"type" : "placeholder" , "name" : "history" },
184+ {"role" : "user" , "content" : "{{question}}" },
185+ ],
186+ type = "chat" ,
187+ )
188+
189+ prompt_client = langfuse .get_prompt (prompt_name , type = "chat" , version = 1 )
190+
191+ # Verify placeholder structure is preserved
192+ assert len (prompt_client .prompt ) == 3
193+
194+ # First message - system with variable
195+ assert prompt_client .prompt [0 ]["type" ] == "message"
196+ assert prompt_client .prompt [0 ]["role" ] == "system"
197+ assert prompt_client .prompt [0 ]["content" ] == "You are {{name}}"
198+ # Placeholder
199+ assert prompt_client .prompt [1 ]["type" ] == "placeholder"
200+ assert prompt_client .prompt [1 ]["name" ] == "history"
201+ # Third message - user with variable
202+ assert prompt_client .prompt [2 ]["type" ] == "message"
203+ assert prompt_client .prompt [2 ]["role" ] == "user"
204+ assert prompt_client .prompt [2 ]["content" ] == "{{question}}"
205+
206+
207+ @pytest .mark .parametrize (
208+ "variables,placeholders,expected_len,expected_contents" ,
209+ [
210+ # Variables only, no placeholders
211+ (
212+ {"role" : "helpful" , "task" : "coding" },
213+ {},
214+ 2 ,
215+ ["You are a helpful assistant" , "Help me with coding" ],
216+ ),
217+ # No variables, no placeholders
218+ ({}, {}, 2 , ["You are a {{role}} assistant" , "Help me with {{task}}" ]),
219+ # Placeholders only, no variables
220+ (
221+ {},
222+ {
223+ "examples" : [
224+ {"role" : "user" , "content" : "Example question" },
225+ {"role" : "assistant" , "content" : "Example answer" },
226+ ]
227+ },
228+ 4 ,
229+ [
230+ "You are a {{role}} assistant" ,
231+ "Example question" ,
232+ "Example answer" ,
233+ "Help me with {{task}}" ,
234+ ],
235+ ),
236+ # Both variables and placeholders
237+ (
238+ {"role" : "helpful" , "task" : "coding" },
239+ {
240+ "examples" : [
241+ {"role" : "user" , "content" : "Show me {{task}}" },
242+ {"role" : "assistant" , "content" : "Here's {{task}}" },
243+ ]
244+ },
245+ 4 ,
246+ [
247+ "You are a helpful assistant" ,
248+ "Show me coding" ,
249+ "Here's coding" ,
250+ "Help me with coding" ,
251+ ],
252+ ),
253+ # Empty placeholder array
254+ (
255+ {"role" : "helpful" , "task" : "coding" },
256+ {"examples" : []},
257+ 2 ,
258+ ["You are a helpful assistant" , "Help me with coding" ],
259+ ),
260+ # Unused placeholders
261+ (
262+ {"role" : "helpful" , "task" : "coding" },
263+ {"unused" : [{"role" : "user" , "content" : "Won't appear" }]},
264+ 2 ,
265+ ["You are a helpful assistant" , "Help me with coding" ],
266+ ),
267+ ],
268+ )
269+ def test_compile_with_placeholders (
270+ variables , placeholders , expected_len , expected_contents
271+ ):
272+ """Test compileWithPlaceholders with different variable/placeholder combinations."""
273+ from langfuse .api .resources .prompts import Prompt_Chat
274+ from langfuse .model import ChatPromptClient
275+
276+ mock_prompt = Prompt_Chat (
277+ name = "test_prompt" ,
278+ version = 1 ,
279+ type = "chat" ,
280+ config = {},
281+ tags = [],
282+ labels = [],
283+ prompt = [
284+ {"role" : "system" , "content" : "You are a {{role}} assistant" },
285+ {"type" : "placeholder" , "name" : "examples" },
286+ {"role" : "user" , "content" : "Help me with {{task}}" },
287+ ],
288+ )
289+
290+ result = ChatPromptClient (mock_prompt ).compileWithPlaceholders (
291+ variables , placeholders
292+ )
293+
294+ assert len (result ) == expected_len
295+ for i , expected_content in enumerate (expected_contents ):
296+ assert result [i ]["content" ] == expected_content
297+
298+
144299def test_compiling_chat_prompt ():
145300 langfuse = Langfuse ()
146301 prompt_name = create_uuid ()
@@ -1165,119 +1320,3 @@ def test_update_prompt():
11651320 expected_labels = sorted (["latest" , "doe" , "production" , "john" ])
11661321 assert sorted (fetched_prompt .labels ) == expected_labels
11671322 assert sorted (updated_prompt .labels ) == expected_labels
1168-
1169-
1170- def test_compile_with_placeholders ():
1171- """Test compileWithPlaceholders method with chat prompt."""
1172- langfuse = Langfuse ()
1173- prompt_name = create_uuid ()
1174-
1175- prompt_client = langfuse .create_prompt (
1176- name = prompt_name ,
1177- prompt = [
1178- {"role" : "system" , "content" : "You are a {{role}} assistant" },
1179- {"role" : "user" , "content" : "Help me with {{task}}" },
1180- ],
1181- labels = ["production" ],
1182- type = "chat" ,
1183- )
1184-
1185- second_prompt_client = langfuse .get_prompt (prompt_name , type = "chat" )
1186-
1187- # Test compileWithPlaceholders with no placeholders (should work like compile)
1188- result = second_prompt_client .compileWithPlaceholders (
1189- variables = {"role" : "helpful" , "task" : "coding" }, placeholders = {}
1190- )
1191-
1192- assert len (result ) == 2
1193- assert result [0 ]["role" ] == "system"
1194- assert result [0 ]["content" ] == "You are a helpful assistant"
1195- assert result [1 ]["role" ] == "user"
1196- assert result [1 ]["content" ] == "Help me with coding"
1197-
1198-
1199- def test_compile_with_placeholders_valid ():
1200- """Test compileWithPlaceholders with valid placeholders."""
1201- from langfuse .api .resources .prompts .types import PromptChatMessage
1202-
1203- langfuse = Langfuse ()
1204- prompt_name = create_uuid ()
1205-
1206- # Create prompt with placeholders
1207- langfuse .create_prompt (
1208- name = prompt_name ,
1209- prompt = [
1210- {"role" : "system" , "content" : "You are a {{role}} assistant" },
1211- {"type" : "placeholder" , "name" : "examples" },
1212- {"role" : "user" , "content" : "Help me with {{task}}" },
1213- ],
1214- type = "chat" ,
1215- )
1216-
1217- prompt_client = langfuse .get_prompt (prompt_name , type = "chat" )
1218-
1219- # Test compileWithPlaceholders with valid placeholders
1220- result = prompt_client .compileWithPlaceholders (
1221- variables = {"role" : "helpful" , "task" : "coding" },
1222- placeholders = {
1223- "examples" : [
1224- PromptChatMessage (role = "user" , content = "Example: {{task}}" ),
1225- PromptChatMessage (role = "assistant" , content = "Example response" ),
1226- ]
1227- },
1228- )
1229-
1230- assert len (result ) == 4
1231- assert result [0 ]["content" ] == "You are a helpful assistant"
1232- assert result [1 ]["content" ] == "Example: coding"
1233- assert result [2 ]["content" ] == "Example response"
1234- assert result [3 ]["content" ] == "Help me with coding"
1235-
1236-
1237- def test_create_prompt_with_placeholders ():
1238- """Test creating a prompt with placeholder messages."""
1239- langfuse = Langfuse ()
1240- prompt_name = create_uuid ()
1241-
1242- prompt_client = langfuse .create_prompt (
1243- name = prompt_name ,
1244- prompt = [
1245- {"role" : "system" , "content" : "System message" },
1246- {"type" : "placeholder" , "name" : "context" },
1247- {"role" : "user" , "content" : "User message" },
1248- ],
1249- type = "chat" ,
1250- )
1251-
1252- # Verify prompt_with_placeholders structure
1253- assert len (prompt_client .prompt_with_placeholders ) == 3
1254- assert prompt_client .prompt_with_placeholders [0 ]["type" ] == "message"
1255- assert prompt_client .prompt_with_placeholders [1 ]["type" ] == "placeholder"
1256- assert prompt_client .prompt_with_placeholders [1 ]["name" ] == "context"
1257- assert prompt_client .prompt_with_placeholders [2 ]["type" ] == "message"
1258-
1259- # Regular prompt should only contain messages
1260- assert len (prompt_client .prompt ) == 2
1261-
1262-
1263- def test_get_prompt_with_placeholders ():
1264- """Test retrieving a prompt with placeholders."""
1265- langfuse = Langfuse ()
1266- prompt_name = create_uuid ()
1267-
1268- langfuse .create_prompt (
1269- name = prompt_name ,
1270- prompt = [
1271- {"role" : "system" , "content" : "You are {{name}}" },
1272- {"type" : "placeholder" , "name" : "history" },
1273- {"role" : "user" , "content" : "{{question}}" },
1274- ],
1275- type = "chat" ,
1276- )
1277-
1278- prompt_client = langfuse .get_prompt (prompt_name , type = "chat" )
1279-
1280- # Verify placeholder structure is preserved
1281- assert len (prompt_client .prompt_with_placeholders ) == 3
1282- assert prompt_client .prompt_with_placeholders [1 ]["type" ] == "placeholder"
1283- assert prompt_client .prompt_with_placeholders [1 ]["name" ] == "history"
0 commit comments